29

一开始我对强制展开和隐式展开非常困惑。现在,以下理解来自我的自学:

没有可用于隐式展开操作,但有一种称为隐式展开的 Optionals 的东西。隐式展开的 Optional 和普通的 Optional 都是 Optional,不同之处在于当访问隐式展开的 Optional 时,您可以自信地知道在后台有一个有效值并可以使用。普通选项需要if let绑定强制展开 ( !) 操作来访问可选变量背后的可能值。

摘要

强制展开是对普通 Optionals执行的操作。

隐式展开的 OptionalsOptionals,通常用于类初始化,使用时将传递不带感叹号的值。

问题

我对吗?如果我的理解不准确,如果您纠正我,我将不胜感激。

谢谢

4

4 回答 4

88

首先让我们定义一个 Optional

Optional 值是某种类型的容器( Int, String, UIColor, ...),它可以包含值 ( 1, "Hello world", .greenColor(), ...) 或nil.

let anOptionalInt: Int? = 1
let anotherOptionalInt: Int? = nil

在此处输入图像描述

在 Swift 中,我们看到一个 Optional 值,我们认为:

好的,这可能包含实际值或nil

强制展开

这是提取包含在Optional. 这个操作很危险,因为你在告诉编译器:我确定这个 Optional 值确实包含一个真实值,提取它!

let anOptionalInt: Int? = 1
let anInt: Int = anOptionalInt!

现在anInt包含值 1。

在此处输入图像描述

如果我们对碰巧包含nil我们得到 a的 Optional 值执行强制解包fatalError,则应用程序确实会崩溃并且无法恢复它。

let anotherOptionalInt: Int? = nil
let anotherInt = anotherOptionalInt!

fatal error: unexpectedly found nil while unwrapping an Optional value

在此处输入图像描述

隐式展开的选项

当我们定义一个隐式展开的可选时,我们定义了一个容器,每次我们读取它时都会自动执行强制展开。

var text: String! = "Hello"

如果现在我们读text

let name = text

我们得到的不是 OptionalString而是普通的String,因为text它的内容是自动展开的。

但是 text 仍然是一个可选的,所以我们可以在nil里面放一个值

text = nil

但是一旦我们阅读它(并且它包含nil),我们就会得到一个致命错误,因为我们正在解开一个可选的包含nil

let anotherName = text

fatal error: unexpectedly found nil while unwrapping an Optional value
于 2016-08-07T19:27:19.283 回答
5

隐式展开的可选项是幕后的普通可选项,但也可以像非可选值一样使用,所以是的,你是正确的。

但是,如果您将一个值声明为隐式展开,则相当于在每次使用时强制展开它。

对于隐式展开的 Optional 有 4 个主要原因。

1:初始化期间无法定义的常量

2:与 Objective-C API 交互

3:当您的应用程序无法从变量中恢复时nil

4:NSObject初始化器

于 2016-08-07T19:13:02.737 回答
2

我会说不,你在画一个错误的区别:

  • 前半句是对的;展开当然是你对 Optionals 做的事情,而强制展开是一种方法(一种不安全的方式)。

  • 但是关于隐式展开的 Optional 是什么:它是一种标记 Optional 类型的方式,以便您完成强制展开(如果您在无法使用 Optional 的地方使用它,但可以在以下情况下使用)它被打开了)。

于 2016-08-07T19:33:33.800 回答
0

隐式展开 当您像这样定义其类型时,您将 Optional 定义为隐式展开。

让 unwrappedString: 字符串!

这种技术允许您告诉编译器自动解包该值,就好像它根本不是可选的一样。类似于类型?这是 Optional, Type! 的语法糖!等效于 ImplicitlyUnwrappedOptional。隐式展开可选的一个常见示例是视图控制器如何定义它们的 IBOutlets:

@IBOutlet var displayLabel:UILabel!@IBOutlet var actionButton:UIButton!

将 outlet 定义为隐式展开的 optional 是有意义的,因为它们将由 Interface Builder 实例化。总是在视图控制器中打开每个视图出口会很麻烦。由于它们隐式展开的性质,如果您忘记将插座连接到它 Interface Builder 查看并运行应用程序,当您尝试在视图控制器中访问它时会出现运行时错误。

于 2020-05-27T11:22:28.637 回答