swift3 学习笔记:?和!区别
?和!区别
var amiteLbl :UILabel?
self.amiteLbl = UILabel(frame:CGRectMake(50,100,200,40))
self.amiteLbl!.text = "I love mixbox"
self.view?.addSubview(self.amiteLbl)
由于amiteLbl是可选变量,所以可能有值,也可能为nil。
使用self.amiteLbl!
是明确声明此时self.amiteLbl
里一定有值,无论什么情况都调用后面的.text赋值方法。
而使用self.view?
是声明此时并不确定self.view里是否有值,所以只在view有值时调用后面.addSubview
方法。
这样做的目的一是让代码更明确, 二是给编译器提供更多线索,在编译时发现更多潜在错误。
! 是强制取值( forced- value) 表达式, ? 是(optional chaining expression) 可选链表达式。
强制取值表达式(Forced-Value Expression)
强制取值表达式用来获取某个目标表达式的值(该目标表达式的值必须不是nil )。它的形式如下:
expression!
如果该表达式的值不是nil, 则返回对应的值。 否则,抛出运行时错误(runtime error)。
强制取值表达式的语法
forced-value-expression → postfix-expression!
可选链表达式(Optional-Chaining Expression)
可选链表达式由目标表达式 + '?' 组成,形式如下:
expression?
后缀'?' 返回目标表达式的值,把它做为可选的参数传递给后续的表达式
如果某个后缀表达式包含了可选链表达式,那么它的执行过程就比较特殊: 首先先判断该可选链表达式的值,如果是 nil, 整个后缀表达式都返回 nil, 如果该可选链的值不是nil, 则正常返回该后缀表达式的值(依次执行它的各个子表达式)。在这两种情况下,该后缀表达式仍然是一个optional type(In either case, the value of the postfix expression is still of an optional type)
如果某个"后缀表达式"的"子表达式"中包含了"可选链表达式",那么只有最外层的表达式返回的才是一个optional type. 例如,在下面的例子中, 如果c 不是nil, 那么 c?.property.performAction() 这句代码在执行时,就会先获得c 的property方法,然后调用 performAction()方法。 然后对于 "c?.property.performAction()" 这个整体,它的返回值是一个optional type.
var c: SomeClass?
var result: Bool? = c?.property.performAction()
如果不使用可选链表达式,那么 上面例子的代码跟下面例子等价:
if let unwrappedC = c {
result = unwrappedC.property.performAction()
}
可选链表达式的语法
optional-chaining-expression → postfix-expression?