【问题标题】:Swift, Optional wrappers. "?" "!" I understand how it works. But why is it better than != nil checkingSwift,可选的包装器。 “?” “!”我明白它是如何工作的。但是为什么它比 != nil 检查好
【发布时间】:2015-05-16 04:55:54
【问题描述】:

我明白如何“!”要么 ”?”作品。但我不太确定与 != nil 检查相比有什么额外的好处。移动到“!?”的额外好处是什么? 我觉得这只是 Apple 添加的东西,但与 iOS 的现状相比,并没有真正看到额外的好处。 我在这里错过了什么吗? 提前致谢。

【问题讨论】:

  • 当我可以将变量声明为非可选并且可以确定它永远不会为 nil 时,为什么每次使用变量时都要检查 nil?
  • 编写更短更易读的代码更方便的功能。它不是 Swift 的典型功能,但也可以在 Groovy 等其他语言中使用。

标签: swift syntax casting operator-keyword


【解决方案1】:

检查 nil 和要求解包可选项之间的区别可能相当于您的代码是否崩溃之间的区别。选项,如果使用得当,可以提高安全性让你的代码更具可读性。

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

if !arr.isEmpty {
    useValue(arr[0])
}

当然,很容易忘记isEmpty 部分,如果你忘记了,你的代码会因为越界错误而崩溃。

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

if let val = arr.first {
    useValue(val)
}

使用此表单,您不会弄错。如果不打开它,就不可能使用arr. first 值。如果你忘记了,你会得到一个编译错误。它对我的眼睛也更具可读性/

大概你会期望你的!= nil 公式能像这样工作:

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

抛开你调用.first 两次这有点低效,以及类型兼容性的问题,基本上这会让你回到第一个问题——你可能会忘记进行nil 比较,然后,卡布姆。或者,您可以采用 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

或可选的比较:

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

}

更多示例,请参阅this answer

【讨论】:

  • 也许你对空值合并不了解:在objective-c 中并没有太大的不同。可以忽略“true”参数以形成语法略有不同的空合并运算符。例如id element = array[0] ?: defaultValue;
  • 为什么你不能在 Objective-C 中写 id first = arr.first; if (first != nil) { ... } ?然后它不会先调用两次。当您发布软件时,您会进行测试以确保它在开发过程中不会崩溃,如果确实如此,您将在开发过程中对其进行修复。当你到达发布阶段时,你的代码相当有信心,没有一堆if let var = something {...} 乱扔你的方法,使你的目标 c 方法又好又短。
【解决方案2】:

? 操作符非常方便,当涉及到链接时,例如:

a?.b?.c?.doSomething()

否则,您将不得不检查abc 是否有nil,这可能会导致比链接更不可读的代码。

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

func someFunc(arg: Type?)

很明显,这是一个可能是nil 的类型,即语言强制执行此操作。否则你会传递一些可能是 nil 的东西,而你会忘记检查并经历崩溃。

【讨论】:

  • 我认为没有人反对您的回答。这是一个非常好的答案。谢谢!!
  • @shle2821,有人做到了。当您获得足够的积分时,您将获得分别查看赞成票和反对票的特权。
猜你喜欢
  • 2019-06-11
  • 2014-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 2019-12-28
相关资源
最近更新 更多