【问题标题】:Swift Optionals - Different ways of unwrappingSwift Optionals - 不同的展开方式
【发布时间】:2015-01-02 14:32:54
【问题描述】:

我会直接说:

两者有什么区别:

var test: String?
test = "this is an optional string"

if test != nil {
    println("\(test!) IS NOT nil")
} else {
    println("test is nil")
}

if let test = test {
    println("\(test) IS NOT nil")
} else {
    println("test is nil")
}

两者在操场上输出相同的结果。

我知道隐式展开不被认为是安全的(在大多数情况下),但是,在这里我在展开之前检查值是否为零?

这两种方法都有效吗?是否存在不同的场景,其中一种被认为是更好的选择?

【问题讨论】:

  • 如果 let 只是在单个语句中展开和测试 nil 的一种模式。阅读链接以获取更多信息。 developer.apple.com/library/ios/documentation/Swift/Conceptual/…
  • 如果我正在审查您的代码,每次强制展开都会在我脑海中发出警钟,我必须检查以确保您已充分防止该变量为零的可能性。如果代码块有很多行并且不是很简单,则尤其如此。

标签: ios swift optional forced-unwrapping


【解决方案1】:

这两种方法都有效吗?是否存在不同的场景,其中一种被认为是更好的选择?

if-let 形式在任何情况下都是更好的选择。! 的正确发音是“我对我的程序的生命发誓”,因为你是。

你的例子是平凡的形式,在平凡的形式中很难看出问题是如何发生的。我刚刚针对nil 进行了测试。会出什么问题?但是软件在增长,软件也在变化。您的!= nil 检查与人们使用了几十年的 C 和 Java 检查相同,并且几十年来一直导致程序崩溃。事实上,很容易错过必要但不是编译器需要的测试。人们一直都在这样做。

当您重新排列代码并将println 移动到一个函数中时,您是否记得也移动了if 测试?在一个大型函数中,if 测试可能在顶部完成,您是否记得在使用 ! 之前完成所有这些测试?重构后是否仍然如此?错误修复后?每次代码更改?

如果您忘记使用if-let 测试nil,那么编译器将阻止您。如果您忘记使用!= nil 进行测试,崩溃会阻止您;希望,如果你很幸运,在单元测试中。如果不是那么幸运,在现场。

也就是说,if-let 并不是唯一好的机制。你也可以map 可选,使用零合并(??),可选链接(?.),这些都是避免错误的优秀工具。但是 Apple 故意选择了!(在 Unix 中被严重称为“bang”)。这是危险的,只有在其他选项不可行时才应谨慎使用。

最后,如果您完美地编写代码,则不需要编译器强加的安全性。您可以在汇编程序中编写代码,完全使用全局内存,并避免我们使用的许多抽象成本。但是人类程序员往往会犯很多小错误,这就是为什么你应该避免!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多