其实我到现在也还没有理解他们具体应该用在什么场合下,教科书的解释都比较繁杂。于是我在写程序的时候常常遇到红色警报,修改建议让我加个“!”,但是加上后它又抱错建议我删除“!”。真是不明白“?”和“!”存在的意义啊,明明其他语言都没见过这样的语法。
1
dorentus 2015-09-07 12:12:47 +08:00 5
在 Swift 里面,关于 Optional 的 ? 和 ! 有以下几种用法:
1 ) 用于类型定义, Type? 其实是 Optional<Type> 的简写,而 Type! 是一种特殊的 Optional 类型( Implicitly Unwrapped Optional )的写法 2 ) ! 用于 Optional 类型变量名的后缀,用于强行解包(失败则触发 runtime error ) 3 ) ? 用于 Optional Chaining ,也是解包,不过失败的话不会触发 runtime error -------- 假设 A 是一个类型,那么 A? 类型(其实是 Optional<A>),其实是一个新的类型,它封装了两种可能性: nil 或者 A 的一个实例。 使用 A? 类型的变量的时候(例如 var a: A?),需要进行判断来解出其中封装的 A 的一个实例值,或者 nil 。解包有好几种方式: 1 ) 直接解,用叹号: let b = a!。如果 a 是 nil 的话,会触发 runtime error 2 ) Optional Binding : if let b = a { /* 这里是有值的情况, b 的类型是 A */ } else { /* 这里是 nil 的情况 */ } 3 ) Optional Chaining : a?.foo () /* 假设 A 定义了 func foo () -> B */,这时假如 a 是 nil ,那么方法调用不会发生;否则的话,方法 foo 被调用,返回一个 Optional<B> 即 B? 的类型的值。 有一些情况,我们明确知道某个变量在我们使用的时候一定非 nil ,但是由于某些限制,无法在声明的时候就初始化(例如 ViewController 里面的 IBOutlet ),那么可以把它声明为 Implicitly Unwrapped Optional 类型,即: var a: A!。对于这种,我们可以像对待 A? 类型的变量一样,去做 Optional Binding 或者 Optional Chaining ,也可以把它当作非 Optional 的 A 类型变量一样直接用(但是如果在用的时候 a 是 nil ,那么会触发 runtime error ) 另外,不要在自己不确定在做什么的前提下去理会修改建议 |
2
machinemxy OP @dorentus 谢谢您耐心的解答。?我已经理解了。关于!,根据您的解答,我的理解是它有两种用法。
第一种是 let b = a! 就是将原本是 A?类型的变量 a 赋值给 b ,然后根据类型推断, b 成为了 A 类型(而不是 A?)。 第二种是 let a = A!,这样定义的话, a 就既可以像 A 类型那样使用,又可以像 A?类型这样使用了。 不知我的理解是否有误。 |
3
dorentus 2015-09-07 12:52:33 +08:00
@machinemxy
假如 a 是 A?; let b = a! 的话,其实 b 是 A! 类型。 let a: A! 来定义的话,这个 a 直接就是 A! 类型。 A! 类型的变量,在用的时候可以不解包直接当成和 A 类型的一样用(但是如果值是 nil 的话就直接闪退了)。然后它也可以当作 A? 类型那样,去手动使用 Optional Binding 或者 Chaining 来解包去判断它是 nil 还是有值。 |
4
dorentus 2015-09-07 12:59:15 +08:00
|
5
machinemxy OP @dorentus 多谢,多亏了你,我才弄懂了这几个概念。
|
6
fhefh 2015-09-07 13:34:42 +08:00
mark 学习了~
|
7
Majirefy 2015-09-07 13:39:34 +08:00
学习学习,的确也不太懂~~
|
8
Bijiabo 2015-09-07 14:16:25 +08:00
学习>_<
|
9
lk920724 2015-09-07 14:18:55 +08:00 1
|
10
wezzard 2015-09-07 14:22:42 +08:00 1
忠告:不要面向黑盒子編程
|
11
machinemxy OP @lk920724 噗…
|
14
DingSoung 2015-09-17 22:12:55 +08:00
还好吧 ,我解析 XML 时被 try catch 整了
|