2017-06-23 126 views
1

我开始让我的头在optionals和强制解包,除了在一个特定的上下文中:当它是一个函数的返回类型。强制解包返回类型?

之间有什么区别:

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

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

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

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

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

为什么我需要?如果我强制解开回报?上述

+0

可能是重复https://stackoverflow.com/questions/24061039/how-is-a-return-value-of-anyobject-different-from-anyobject – rmaddy

+1

对于'NSData',这两者之间没有什么不同两行代码。你可以在@rmaddy发送的链接中找到Rob的一个很好的解释。 – Lawliet

+3

在实践中**从不**使用隐式展开的可选值作为函数/方法中的返回类型。这个值可以是'nil',然后使用'?'或者该值永远不会'nil',然后使用'non-optional'。 – vadian

回答

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

意味着myFunction返回NSData一个实例。上述


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

意味着myFunction返回Optional<NSData>型(也称为NSData?)的值。 Optionalenum,有两种情况:.some(value).none(也称为nil)。因此该函数返回NSData(包装在.some的情况下)或nil。上述


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

意味着myFunction返回Optional<NSData>类型,就像在前面的例子中NSData?返回类型的值。

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

let maybeLength = myFunction()?.length 

那么编译器会看到,你是治疗的myFunction返回值作为Optional<NSData>。但是,如果你这样说:

let dataLength = myFunction().length 

那么编译器会看到Optional<NSData>没有length成员,因此它会假装你写了这个:

let dataLength = myFunction()!.length 

,如果可以编译,它会继续。

此行为在Swift Evolution proposal SE-0054, Abolish ImplicitlyUnwrappedOptional type中定义。


现在我们终于可以这样考虑:

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

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

编译器没有遇到任何问题,使得data的类型为NSData?,所以它没有理由隐式地解开返回值myFunction

+0

太棒了!谢谢! –