Swift,可选包装器."?" "!" 我明白它是如何工作的.但为什么它比!= nil检查更好

shl*_*821 5 syntax casting operator-keyword swift

我明白"!" 要么 "?" 作品.但我不太确定与之相比的额外好处是什么!= nil checking.转移到"!?"的额外好处是什么?我觉得这只是Apple添加的东西,但与iOS现状相比,无法真正看到额外的好处.我错过了什么吗?提前致谢.

Seb*_*ler 5

?链接时,操作员非常方便,例如:

a?.b?.c?.doSomething()
Run Code Online (Sandbox Code Playgroud)

否则,你就必须检查a,bc进行nil,这可能导致更多的不可读的代码要比链一样.

另一件事是,您可以轻松地将参数标记为可选,例如

func someFunc(arg: Type?)
Run Code Online (Sandbox Code Playgroud)

并且很明显,这是一种类型nil,即语言强制执行此类型.否则你会传递一些可能的东西,你会nil忘记检查并遇到崩溃.


Air*_*ity 5

检查nil和要求可选的unwrapped之间的区别可能相当于代码崩溃与否之间的差异.选配,正确使用,既可以提高安全性,并让你的代码更易读.

假设您有一个数组,并且想要获取其中的第一个值.你可以这样做:

if !arr.isEmpty {
    useValue(arr[0])
}
Run Code Online (Sandbox Code Playgroud)

但是,当然,很容易忘记那isEmpty部分,如果你这样做,你的代码会因为越界错误而崩溃.

所以,有一个更好的方法:使用数组的first方法,nil如果数组为空,则返回一个可选的方法:

if let val = arr.first {
    useValue(val)
}
Run Code Online (Sandbox Code Playgroud)

有了这个表格,你不会错.如果arr. first不打开它就不可能使用它.如果您忘记了,则会出现编译错误.它对我的眼睛也更具可读性/

大概你会希望你的!= nil配方能像这样工作:

if arr.first != nil {
    // all optionals would be “implicit”
    useValue(arr.first)
}
Run Code Online (Sandbox Code Playgroud)

暂且不说你打电话.first两次效率有点低,而且类型兼容性的问题,基本上会让你回到nil原点- 你可能会忘记进行比较,然后是kaboom.或者,您可以采用Objective-C方法,并说nil可以发送消息 - 但这也会导致各种混淆(个人我讨厌隐含发送消息的意思,nil意味着无操作),还有导致这个问题,做什么,当函数返回值类型,如你做Int.一切都可以为空吗?这导致了Obj-C土地的混乱.

更重要的是,一旦你处理了可选项,你可以引入各种各样的便利,比如nil-coalescing:

// default to 0 if no first element
arr.first ?? 0
// much neater than this equivalent form:
arr.first != nil ? arr.first : 0
Run Code Online (Sandbox Code Playgroud)

或可选比较:

// will only be true if arr is non-nil and zero
if arr.first == 0 {

}
Run Code Online (Sandbox Code Playgroud)

有关更多示例,请参阅此答案