【问题标题】:Not using unwrapping in guard statements在保护语句中不使用展开
【发布时间】:2016-07-15 19:37:15
【问题描述】:

我充分了解可选项的使用,知道何时需要使用感叹号解开可选项。为什么保护语句中不需要感叹号?

此代码可以工作并编译,但不使用感叹号:

struct Blog{

  var author:String?
  var name: String?

}

func blogInfo2(blog:Blog?){
  guard let blog = blog else {
    print("Blog is nil")
    return
  }
  guard let author = blog.author, name = blog.name else {
    print("Author or name is nil")
    return
  }
  print("BLOG:")
  print(" Author: \(author)")
  print(" name: \(name)")
}

如果您确实输入了感叹号,此代码也可以使用:

struct Blog{

  var author:String?
  var name: String?

}

func blogInfo2(blog:Blog?){
  guard let blog = blog! else {
    print("Blog is nil")
    return
  }
  guard let author = blog.author!, name = blog.name! else {
    print("Author or name is nil")
    return
  }
  print("BLOG:")
  print(" Author: \(author)")
  print(" name: \(name)")
}

这是不是有点矛盾,或者有人可以清楚地解释为什么不需要感叹号吗?

【问题讨论】:

  • 我很惊讶guard let blog = blog! 版本适合您。你用的是什么版本的 Swift?
  • @PhillipMills 是的,现在我在在线快速编译器中尝试后意识到,因为我使用的是 Xcode 8 测试版

标签: ios swift optional forced-unwrapping


【解决方案1】:

guard let unwrapped = optionalOptional Binding(不幸的是,没有直接指向正确书籍部分的链接)。它安全地尝试解开可选中的值。如果有值,则解包成功,并将值分配给给定的名称。

您应该大力支持使用可选绑定,使用guardif(区别在于“展开”名称的范围)而不是使用! 强制展开。强制展开失败是一个致命错误;你的程序只会崩溃。

【讨论】:

    【解决方案2】:

    我充分了解可选项的使用,知道何时需要使用感叹号解开可选项。

    如果你做出这样的断言,我感觉你足够理解 Swift Optionals。

    Optional 背后的契约是它可能是 nil 也可能不是 nil;你不知道它,因此你必须先打开它(比如打开一个盒子,看看里面有什么),然后才能知道。

    该框可能是空的(nil 可选)或者它可能包含一个值。

    很少有理由使用强制展开 (!)。 很少,并且在大多数(但不是全部)情况下通常被认为是一种不好的做法。

    继续进行类比,通过强制打开东西,你是在说这个盒子里有东西,我希望你相信我,不要检查

    知道空盒子会崩溃您的应用程序,这是一件非常危险的事情,考虑到 Swift 中引入了 Optional 来保护您免受此类崩溃的影响首先。

    if let/guard let 语句基本上是在盒子里面偷看,如果有东西,它们会给你,但如果盒子是空的,它们也让你有机会做其他事情。

    Xcode 在使用 IBOutlets 时会强制展开,因为按设计约定是这些对象在您可以使用它们时将可用在您的视图控制器中,但除非您 100% 确定一个值不会是 nil,否则使用 guard 语句(或 if)几乎总是更好(和未来证明)。

    根据我的经验,即使您肯定知道,扔guard 并忘记未来可能出现的问题仍然更安全。

    【讨论】:

    • 我想说! 的使用仅限于两​​种情况。 a/ 当您无法真正从该错误中恢复时(例如,由于内存分配失败而返回 nil) b/ 当 nil 应被视为编程错误时。例如,从 literal 字符串创建 URL 时。在这种情况下,! 用作断言。
    • @Sulthan 同意在极少数的情况下,! 是可以的,通常取决于项目,但通常更喜欢优雅地处理错误(内存分配失败)并提供替代方案或通知用户发生的事情,而不是简单的崩溃;崩溃是最坏的结果,不惜一切代价避免它。语言/框架为您提供了执行此操作的工具。
    【解决方案3】:

    感叹号“force”解开一个可选项。 guard letif let 会在不强制任何内容的情况下展开它,因此不使用感叹号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-11
      • 1970-01-01
      • 2018-03-03
      • 1970-01-01
      • 1970-01-01
      • 2021-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多