可选项的本质是enum类型
API
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T?) rethrows -> T?
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T
规则
a ?? b
-
a
是可选项 -
b
是可选项 或者 不是可选项 -
b
跟a
的存储类型必须相同 - 如果
a
不为nil
,就返回a - 如果
a
为nil
,就返回b
- 如果
b
不是可选项,返回a
时会自动解包
举例
let a: Int? = 1
let b: Int? = 2
let c = a ?? b // let c: Int? Optional(1)
let a: Int? = nil
let b: Int? = 2
let c = a ?? b //let c: Int? Optional(2)
let a: Int? = nil
let b: Int? = nil
let c = a ?? b //let c: Int? , nil
let a: Int? = 1
let b: Int = 2
let c = a ?? b //let c: Int , 1
let a: Int? = nil
let b: Int = 2
let c = a ?? b // let c: Int , 2
?? 跟if let 配合使用
let a: Int? = nil
let b: Int? = 2
if let c = a ?? b {
print(c)
}
这样做的好处是,当你不清楚b的类型的时候,编译器如果报错,说明b不是可选类型
因为既然使用if let 语法,a ?? b 的值必须是可选类型,那么也就说明,b必须是可选类型
注意事项(纯Swift
不用考虑,swift
是安全的语言。Objective-C
和Swift
混编要注意)
自从开始使用swift
写项目的时候,更加注意数据类型,不然会引起严重bug!
举例
在纯swift
开发的过程中,一般不会出现数据类型出错,因为系统可以检测出数据类型不一致,无法编译通过。
Swift
和Objective-C
混编的时候,Objective-C
是没有可选类型这个概念的
如果把Objective-C
的NSString
类型直接赋给Swift中的
String类型的时候,编译器是不会报错的!
当Objective-C
的NSString
的值为nil
的时候,问题就出现了,这个时候Swift
中的String
类型就无法接受nil
而且更可怕的是,这个时候编译器是不会报错的!!!
所以,在遇到swift类型接收Objective-C
类型的时候,一定要确认Objective-C
的数据类型。
如果Objective-C
定义数据类型,没有设置nonnull
,此时Objective-C
的数据类型是允许为nil的