购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

Tip 6

Optional Chaining

使用Optional Chaining可以让我们摆脱很多不必要的判断和取值,但是在使用的时候需要小心陷阱。

因为Optional Chaining是随时都可能提前返回nil的,所以使用Optional Chaining所得到的东西其实都是Optional的。比如有下面的一段代码:

在实际使用中,我们想知道小明的宠物的玩具的名字的时候,可以通过下面的Optional Chaining得到:

注意虽然我们最后访问的是name,并且在Toy的定义中name是被定义为一个确定的String而非String?的,但是我们得到的toyName其实还是一个String?的类型。这是由于在Optional Chaining中,我们在任意一个?.的时候都可能遇到nil而提前返回,这个时候当然就只能得到nil了。

在实际使用中,我们在大多数情况下可能更希望使用Optional Binding来直接取值的代码:

可能单独拿出来看会很清楚,但是只要稍微和其他特性结合一下,事情就会变得复杂起来。来看看下面的例子:

我们为Toy定义了一个扩展,以及一个玩玩具的play()方法。还是拿小明举例子,要是有玩具,小明就玩玩具:

除了小明,也许还有小红、小李、小张等,这时候我们会想要把这一串调用抽象出来,做一个闭包以方便使用。传入一个Child对象,如果小朋友有宠物并且宠物有玩具的话,就去玩,于是你很可能写出这样的代码:

这是错误代码

这样的代码是没有意义的!

问题出在对play()的调用上。定义的时候我们没有写play()的返回,这表示这个方法返回Void(或者写成一对小括号(),它们是等价的)。但是正如上面所说,经过Optional Chaining以后我们得到的是一个Optional的结果。也就是说,我们最后得到的应该是这样一个closure:

这样调用的返回将是一个()?(或者写成Void?会更清楚一些)。虽然看起来挺奇怪的,但这就是事实。使用的时候我们可以通过Optional Binding来判定方法是否调用成功: Hq9trFb7bCN5aMzl/Fv4Ydu9TyQTtv6atMSgAWthU4Z9hfx4vuOCMF+ibFinLmvV

点击中间区域
呼出菜单
上一章
目录
下一章
×