不在 guard 语句中使用展开

Not using unwrapping in guard statements

我了解可选值的使用,足以知道何时需要使用感叹号解包可选值。为什么在 guard 语句中不需要感叹号?

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

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)")
}

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

感叹号 "force" 展开一个可选的。 guard letif let 解包而不强制任何内容,因此不使用感叹号。

guard let unwrapped = optional 是一个 Optional Binding(不幸的是,没有 link 可以直接用于正确的书籍部分)。它安全地 尝试解包可选中的值。如果有值,则解包成功,并将该值分配给给定的名称。

您应该非常喜欢使用可选绑定,使用 guardif(区别在于 "unwrapped" 名称的范围)而不是使用强制解包!。强制解包失败是 致命错误;你的程序会崩溃。

I understand the use of optionals enough to know when its necessary to unwrap an optional using the exclamation point.

我觉得如果您做出这样的断言,您并不充分理解Swift可选项。

Optional 背后的约定是它可能为 nil,也可能不为 nil;你不知道它,因此你必须打开它(就像打开一个盒子,看看里面有什么)才能分辨。

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

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

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

知道空框会 崩溃 你的应用程序,这是一件非常危险的事情,考虑到在 Swift 到 中引入了 Optionals从一开始就保护 你免受这些崩溃的影响。

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

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

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