🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## OPTIONALS Apple 在 Swift 中为其加入了 Optional,Optional 是一种类型,可以有值,也可以等于 nil(也就是没有值)。在 oc 中,只有指向对象的指针可以为 nil,而在 swift 中基本类型创建后没有初始值,而是为 nil,并且无法使用。 开发中遇到的一些意想不到的问题,例如程序崩溃、影响UI,最常见的原因就是因为使用了为 nil 的值,Optional 这一特性确保了代码安全性。 * 定义一个 Optional 的值只需在类型后添加一个问号“?”: ~~~ var str: String? //输出nil //以上是一个名为 str 的 Optional String. ~~~ * Optional 类型无法直接使用,需要拆包(unwrap)后取出原类型的值后使用。在 Optional 类型后加上感叹号(!)进行显式拆包(Force unwrapping optionals): ~~~ var str: String? = "Hallo World" str //nil str! //"Hallo World" print(str) //输出"Optional("Hallo World")" print(str!) //输出"Hallo World" ~~~ * 通过 if let 语句可以判断 Optional 是否有值,如果有,将其拆包赋值给一个本地变量: ~~~ func getHaterStatus(weather: String) -> String? { if weather == "sunny" { return nil } else { return "Hate" } //该方法返回一个 Optional String 类型 } func takeHaterAction(status: String) { if status == "Hate" { print("Hating") } //该方法需要传入一个 String 类型 } if let status = getHaterStatus("rainy") { takeHaterAction(status) /* if let 语句将调用了 getHaterStatus 方法后得到的 Optional 值拆包后赋值给本地变量 status,确保 takeHaterAction 方法传入的是一个有值的参数。 */ } ~~~ * Optional 还提供了隐式拆包(implicitly unwrapped optionals),隐式拆包的 Optional 在使用前无需拆包。要使用隐式拆包需要在变量声明时的数据类型后加上感叹号(!): ~~~ var str: String! = "Hello World!" str //Hello World! ~~~ 使用隐式拆包需要小心,要确保变量已被正确初始化。一般会在以下情况遇到 Implicitly unwrapped: 1. 当使用 Apple 的 API 时会经常碰到隐式拆包的返回值。 2. 当使用 UIKit 的用户界面元素时。 ### 总结一下 Optional: * 一个普通类型的变量必须有值,比如一个 String 变量需要拥有一个 string,哪怕是空的字符串("“)。 * 一个 Optional 类型的变量可以有值也可以无值(也就是为nil),但在使用前必须将其拆包(Unwrap)。 * 一个隐式拆包的 Optional 类型变量可以有值也可以无值,使用前不需要拆包,因此 Swift 也不会为你检查,需要格外小心。 * * * * Optional Chaining: 在 Objective-C 中,对 nil 发送消息会得到 nil,但是在 Swift 中不允许这么做。当对一个 Optional 类型的对象发送消息时,通过 Optional Chaining 可以对其判断是否有值,如果是则发送消息,反之则什么也不做: ~~~ func albumReleasedYear(year: Int) -> String? { switch year { case 2006: return "Taylor Swift" case 2008: return "Fearless" case 2010: return "Speak Now" case 2012: return "Red" case 2014: return "1989" default: return nil } } let album = albumReleasedYear(2006)?.uppercaseString //输出 Optional("TAYLOR SWFIT") //即问号(?)前有值才发送消息,这就是 Optional Chaining Optional Chaining 如同其名可以像链条一样连接,多长都可以,Swift 会从左至右检查直至发现 nil 即终止: let album = albumReleasedYear(2006)?.someOptionalValue?.someOtherOptionalValue?.whatever ~~~ * The nil coalescing operator: Swift 的这个特性可以让你的代码更加简单和安全。例如:当 Value A 有值时则使用 Value A,如果 Value A 无值,则使用 Value B,这对 Optional 十分有用: ~~~ let album = albumReleasedYear(2006) ?? "unknown" print("The album is \(album)") //如果 albumReleasedYear(2006)返回的 Optional 无值,则使用非 Optional "unknown". ~~~