swift是一门类型安全的编程语言,声明的变量默认情况下是不能为非空值(nil)的,如果需要这个变量可为nil,那么就需要设置为可选类型。
可选类型其根源是一个枚举型,里面有None和Some两种类型。其实所谓的nil就是Optional.None, 非nil就是Optional.Some, 然后会通过Some(T)包装(wrap)原始值,这也是为什么在使用Optional的时候要拆包(从enum里取出来原始值)的原因.
强制解析
上面说到可选型使用Some(T)包装(wrap)了原始值
如图,即使我们知道str有值,但是直接输出是可选型而不是String类型。
那么要从str中获得它的字符串值该如何获得
swift中使用!来进行解包,即
获得的就是str的字符串值
注意:! 强制解析时必须保证可选类型不为nil,否则强制解析一个为nil的可选类型会报错
fatal error: unexpectedly found nil while unwrapping an Optional value
自动解析
在声明可选型的时候把?替换为!即可。这样可选变量在使用时就不需要再加一个感叹号(!)来获取值,它会自动解析。
可以看出,使用!声明的类型仍然是可选类型,在str为nil时仍为nil,在strTest有值时不需要使用strTest!就可以取到字符串值。
强制解析与自动解析中的 ! 区别
在声明时的 ! 只是对可选类型的一种声明方式。误区:有些人认为使用!声明的变量就必须为非空,其实不是这个意思。这里的 !是说在非空时str1取值取到的是解包后的值,而不再是Optional();
在调用时的 ! 是强制解包,也就是求取Optional.Some(T)包装下的值,所以为 Optional值 = nil 时会报错
可选绑定
既然可选型可以为空,那么通常我们需要判断非空时要怎么处理,为nil时应该怎么处理。
最常用的判断方式就是if语句了
这是我们熟悉的if语句写法,swift提供了更方便的if let/var语句,也称为可选绑定
为什么称if let是一个语句而不再是 if语句呢,因为
if let strTemp = str5 时进行的是解析赋值。strTemp1 = str5!这时才和strTemp值相等。
xcode中输入iflet会自动补全就像是forin语句,但是ifvar不会不全,但是不代表ifvar不可以
可选链 Optional chaining
为什么会有可选链呢?
如图,我们使用可选值变量的时候各种判断有时候还需要if嵌套真的很麻烦,所以出现了可选链
通过 ? 语法调用属性或者方法。即?出现在调用时,而不是出现在变量的定义中,称为可选链。
?返回一个可选值, 可选值为nil则代码语句执行结果为nil,可选值非空则继续往下执行。
如:people.money?.canBuyIphone()中如果money为nil,则整个语句返回nil。如果money有值则执行canBuyIphone()方法,判断是否能购买iPhone
也就是说可选链是一个可选值,一个为nil,一个为非nil
空合运算符 ??
什么是空合运算符呢, 符号表示就是 ?? ,有点类似三目运算符?:的变种
还是上面的例子,我们把if let语句改成了三目运算符,有没有发现可选链组成的三目运算符是相当的霸气。而使用 ?? (空合运算符)就简短了不少。
x ?? y表示判断x是否为nil,若不为nil,则将x解包后返回,否则,取y的值