我们用oc开发的时候,经常会遇到null值的情况,如果不加任何判断的话可能会导致程序崩溃,swift语言添加了可选值这样的概念,基本语法如下:

可选类型:


  1. var optValue: Int? = 8  

在类型后面加一个?表示optValue这个值可以为nil,"?"就是可选值的一个标记,?其实是一个Optionals的类型,我们可以看看swift的源码:


  1. enum Optional<T> : Reflectable, NilLiteralConvertible {  

  2. case None  

  3. case Some(T)  

  4.   

  5. /// Construct a `nil` instance.  

  6. init()  

  7.   

  8. /// Construct a non-\ `nil` instance that stores `some`.  

  9. init(_ some: T)  

  10.   

  11. /// If `self == nil`, returns `nil`.  Otherwise, returns `f(self!)`.  

  12. func map<U>(f: (T) -> U) -> U?  

  13.   

  14. /// Returns a mirror that reflects `self`.  

  15. func getMirror() -> MirrorType  

  16.   

  17. /// Create an instance initialized with `nil`.  

  18. init(nilLiteral: ())  

  19. }  


从源码可以看出,Optionals类型其实是一个枚举类型,一个是none,一个是非none:

因为optValue是一个可选值,所以可以把nil赋值给optValue,看看下面的代码:


  1. var optValue: Int? = 8  

  2. optValue = nil  

  3. let optValue2 = optValue  

  4. print(optValue2)  

这时候optValue是nil,把它赋值给optValue2的时候,程序会崩溃,但是可以用下面的方式:


  1. var optValue: Int? = 8  

  2. optValue = nil  

  3.   

  4. if let t = optValue {  

  5.     print("\(t)")  

  6. }else{  

  7.     print("nil")  

  8. }  


如果optValue是nil,那么就不会执行赋值语句,程序就会打印nil出来,这就是可选绑定。


当需要对optValue强制解包的时候,在变量后面加一个!

比如:


  1. var optValue: Int? = 8  

  2.   

  3. var t: Int = optValue!  

  4. print(t)  


这个时候会把optValue里面的int类型的值强制解包出来赋值给t,打印出来的值也是8;



隐式解析可选

有时候在程序架构中,第一次被赋值之后,可以确定一个可选总会有值。在这种情况下,每次都要判断和解析可选值是非常低效的,因为可以确定它总会有值。


这种类型的可选被定义为隐式解析可选(implicitly unwrapped optionals)。把想要用作可 选的类型的后面的问号(String?)改成感叹号(String!)来声明一个隐式解析可选。

当可选被第一次赋值之后就可以确定之后一直有值的时候,隐式解析可选非常有用。


  1. let optValue: Int! = 8  

  2. if optValue != nil {  

  3.     print(optValue)  

  4. }  

  5.   

  6. if let t = optValue {  

  7.     print(t)  

  8. }  

  9.   

  10. var tm: Int = optValue  

  11. print(tm)  


你可以把隐式解析可选当做一个可以自动解析的可选。你要做的只是声明的时候把感叹号放到类型的结尾,而不是每次取值的可选名字的结尾。
注意:如果你在隐式解析可选没有值的时候尝试取值,会触发运行时错误。和你在没有值的普通可选后面加一个惊叹号一样。