为什么要创建“隐式解包选项”,因为这意味着您知道有一个值?

2023-12-31

为什么要创建“隐式解包可选”而不是仅创建常规变量或常量? 如果您知道它可以成功解包,那么为什么首先要创建一个可选呢? 例如,这是为什么:

let someString: String! = "this is the string"

将比以下更有用:

let someString: String = "this is the string"

如果“可选值表明允许常量或变量具有‘无值’”,但是“有时从程序的结构中可以清楚地看出,在首次设置该值之后,可选值将始终具有值”,那么有什么意义呢?首先让它成为可选的? 如果你知道一个可选值总是有一个值,那么这是否就意味着它不是可选的?


在我描述隐式解包选项的用例之前,您应该已经了解 Swift 中的选项和隐式解包选项是什么。如果你不这样做,我建议你先阅读我关于选项的文章 http://www.drewag.me/posts/what-is-an-optional-in-swift

何时使用隐式解包可选

创建隐式解包可选有两个主要原因。所有这些都与定义一个永远不会被访问的变量有关nil因为否则,Swift 编译器将始终强制您显式解开一个Optional。

1. 初始化时无法定义的常量

在初始化完成时,每个成员常量都必须有一个值。有时,常量在初始化时无法用正确的值进行初始化,但仍然可以保证在访问之前它有一个值。

使用可选变量可以解决此问题,因为可选变量会自动初始化为nil并且它最终包含的值仍然是不可变的。然而,不断地解开一个你确信不为零的变量可能会很痛苦。隐式解包的Options 实现了与Optional 相同的好处,但额外的好处是不必在任何地方显式地解包它。

一个很好的例子是,在加载视图之前,无法在 UIView 子类中初始化成员变量:

class MyView: UIView {
    @IBOutlet var button: UIButton!
    var buttonOriginalWidth: CGFloat!

    override func awakeFromNib() {
        self.buttonOriginalWidth = self.button.frame.size.width
    }
}

在这里,在视图加载之前您无法计算按钮的原始宽度,但您知道awakeFromNib将在视图上的任何其他方法(初始化除外)之前调用。您可以将其声明为隐式解包可选,而不是强制在整个类中毫无意义地显式解包该值。

2. 当你的应用程序无法从变量中恢复时nil

这应该是极其罕见的,但是如果你的应用程序无法继续运行,如果变量是nil当访问时,费心测试它是浪费时间nil。通常,如果您的应用程序必须满足一个条件才能继续运行,那么您将使用assert。隐式解包可选有一个内置的 nil 断言。即使如此,如果它为 nil,最好解开可选值并使用更具描述性的断言。

何时不使用隐式解包可选

1. 延迟计算成员变量

有时你有一个不应该为 nil 的成员变量,但在初始化期间无法将其设置为正确的值。一种解决方案是使用隐式解包可选,但更好的方法是使用惰性变量:

class FileSystemItem {
}

class Directory : FileSystemItem {
    lazy var contents : [FileSystemItem] = {
        var loadedContents = [FileSystemItem]()
        // load contents and append to loadedContents
        return loadedContents
    }()
}

现在,成员变量contents直到第一次访问时才初始化。这使类有机会在计算初始值之前进入正确的状态。

Note:这似乎与上面的#1 相矛盾。然而,有一个重要的区别需要做出。这buttonOriginalWidth上述必须在 viewDidLoad 期间设置,以防止任何人在访问该属性之前更改按钮宽度。

2. 其他地方

在大多数情况下,应该避免隐式解包选项,因为如果使用错误,整个应用程序将在访问时崩溃nil。如果您不确定变量是否可以为零,请始终默认使用普通的Optional。解开一个永远不会存在的变量nil当然不会很痛。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么要创建“隐式解包选项”,因为这意味着您知道有一个值? 的相关文章

随机推荐

  • 与重复的组合

    我正在使用 Mathematica 7 和 Combinatorica 包函数 我可以从元素列表中获取特定数量的所有组合 其中顺序无关紧要并且没有重复 例如 in KSubsets a b c d 3 out a b c a b d a c
  • 如何检查仅当鼠标位于特定位置时才存在的元素

    如果您需要检查元素的悬停状态 可以按照描述完成here https stackoverflow com questions 17602611 inspect a hover element问题是如果移动鼠标就会失去状态 就我而言 它的 ja
  • 绑定Vuejs的两个组件

    如何完美地组织两个 vuejs 组件之间的数据和交互 例如 1 我有一个组件 item v for item in items a item name 2 和第二个 card v for item in items div content
  • 如何停靠弹出窗口?

    我有一个包含 3 个主要小部件的应用程序 我也有一个弹出窗口QDockWidget 我正在尝试获取QDockWidget停靠到底部小部件的右半部分 但正如您在下图中看到的 我可以停靠窗口的唯一位置是应用程序的边缘 我怎样才能做到这一点QDo
  • 闪亮的传单地图弹出窗口正在提取错误的数据

    由于某种原因 Shiny传单应用程序上分配给多边形的弹出窗口提取了应分配给多边形的错误信息 似乎多边形已放置在地图上 然后以不同的顺序分配多边形属性 任何想法将不胜感激 server lt function input output ses
  • Google Cloud Load Balancer - 子域重定向到存储桶中的特定文件夹

    目前我们有以下需求 每个用户都可以在 Google 存储桶下拥有自己的子域和文件夹 其中包含应通过此子域提供的内容 例如 domain user1 example com gt bucket example com user1 index
  • 如何将表中的某些列复制到另一个mysql

    我有两张桌子 例如 table 1 A B C D E F G H I J table 2 A C D E G H J K L M N O P 我必须将一些列从表 2 复制到表 1 我尝试的是 INSERT INTO table 1 C D
  • json_encode PHP 对象及其受保护的属性

    有什么方法可以设置 PHP 对象 以便当我尝试将它们转换为 JSON 时 它们所有受保护的属性都会显示出来 我读过其他答案建议我添加一个toJson 函数到对象 但这可能并不能真正帮助我很多 在大多数情况下 我有一个对象数组 并对数组本身执
  • 在 Windows 窗体上的窗口一侧添加按钮

    我想在 C 上的 Windows 窗体一侧添加按钮 在外面 当窗口移动时 按钮应该一起移动 例如 我看到两个选择 要么将按钮放在单独的表单中 然后通过编码将两个表单粘在一起Move有可能Resize events 或者更简单 制作表格透明的
  • 在新行中添加 max(value)+1,这会是一个问题吗?

    在 SQL Server 表中 我有以下两列 RowId 主键 数字 标识列和自动插入 MailId 非键 数字 非标识 非自动插入 邮件 ID 可以重复 如果是新的 MailId 我将检查 max MailId 1 并将其插入新行中 如果
  • 如何在gridview中间歇性地展示横幅广告

    I am developing an android app that will have a screen similar to the following image 请注意单元格之间的横幅广告 由于 GridView 不支持这种跨列
  • 为什么在 epoll 中推荐使用非阻塞套接字

    我正在尝试学习如何将 epoll 用于 tcp 服务器应用程序 因为我期望有很多连接 我尝试检查示例和教程 他们总是建议使用 设置在 epoll 中添加的套接字为非阻塞套接字 为什么 对于级别触发的 epoll 非阻塞套接字可以帮助最大限度
  • C# Groupby 然后在分割 CSV 后求和(无标题)

    阅读了各种帖子后 我认为我已经接近得到我想要的结果 但 总和 部分给出了错误的答案 我怀疑这是由于我调用 总和 的方式造成的 因为我的 csv 文件没有列标题 csv 文件包含以下内容 222 1 223 2 222 1 224 2 222
  • 偏移GPS坐标的公式/算法

    我以纬度 经度的形式提供 GPS 坐标 并希望将它们偏移距离和角度 例如 如果我偏移 新坐标是多少45 12345 7 34567沿方位 104 度行驶 22 公里 Thanks 对于大多数应用 这两个公式之一就足够了 给定径向和距离的纬度
  • 收到错误 /bin/sh: 1: 源: 未找到

    我正在尝试构建 docker 并安装 nvm 一些代码行 RUN curl https raw githubusercontent com creationix nvm v0 25 0 install sh bash RUN source
  • 使用 Visual Studio 扩展设置光标位置

    我正在编写自己的 Visual Studio 2010 扩展 它应该可以帮助我浏览一个相当大的解决方案 我已经有一个基于对话框的 VS 扩展 它根据某些搜索条件显示类名和函数名 我现在可以单击此类 方法 然后我就可以打开正确的文件并跳转到该
  • C# OpenGL字体显示

    我正在Windows中使用Tao框架开发2D CAD应用程序 我想使用 Windows 库中的字体来显示绘图信息 除此之外 我想旋转缩放我的文本 对于位图字体我无法做到这一点 我进行了 OpenGL 字体调查 http www opengl
  • SQL-合并两个具有不同日期值的表

    我正在开发一个在网站上显示股票信息的项目 我想问一下如何在SQL中合并两个表 假设我们有表1 stock id date p high p low 3 2013 02 26 100 80 3 2013 02 25 100 80 3 2013
  • 如何使用python获取一列数据中包含的特定行的时间差

    这里我有一个包含时间和三个输入的数据集 这里我用panda来计算时差 代码是 data Time different pd to timedelta data time astype str diff 1 dt total seconds
  • 为什么要创建“隐式解包选项”,因为这意味着您知道有一个值?

    为什么要创建 隐式解包可选 而不是仅创建常规变量或常量 如果您知道它可以成功解包 那么为什么首先要创建一个可选呢 例如 这是为什么 let someString String this is the string 将比以下更有用 let s