1

我开始考虑选项和强制展开,除了在一个特定的上下文中:当它是函数的返回类型时。

有什么区别:

func myFunction() -> NSData { ... }

func myFunction() -> NSData! { ... }

func myFunction() -> NSData? { ... }

此外,当我使用 的返回值时NSData!,我被迫使用?这似乎很奇怪。

func myFunction() -> NSData! { ... }
let data = myFunction()
data?.write()

?如果我强制打开退货,为什么我需要?

4

1 回答 1

7
func myFunction() -> NSData { ... }

上面的意思是myFunction返回一个NSData.


func myFunction() -> NSData? { ... }

上面的意思是myFunction返回一个类型的值Optional<NSData>(也称为NSData?)。Optional是一个enum有两种情况:.some(value).none(也称为nil)。因此,该函数返回一个NSData(包装在.some案例中)或nil.


func myFunction() -> NSData! { ... }

上面的意思是myFunction返回一个 type 的值Optional<NSData>就像NSData?前面例子中的返回类型一样。

但是,使用的!意思是,如果您以myFunction()不进行类型检查的方式使用值,编译器将尝试为您解开返回的值。所以如果你这样说:

let maybeLength = myFunction()?.length

然后编译器将看到您将 的返回值myFunction视为Optional<NSData>. 但如果你这样说:

let dataLength = myFunction().length

然后编译器会看到Optional<NSData>没有length成员,所以它会假装你写了这个:

let dataLength = myFunction()!.length

如果编译成功,它将继续。

这种行为是在Swift Evolution 提案 SE-0054, Abolish ImplicitlyUnwrappedOptionaltype中定义的。


现在让我们最终考虑一下:

func myFunction() -> NSData! { ... }
let data = myFunction()
data?.write()

是什么类型的datadata编译器必须根据 . 右侧的表达式来推断=. 正如我在上面的示例中所解释的,类型myFunction()Optional<NSData>. 所以类型dataOptional<NSData>,也叫NSData?

data编译器在生成' 类型时不会遇到任何问题NSData?,因此没有理由隐式解开 . 的返回值myFunction

于 2017-06-23T05:53:44.877 回答