Swift 为什么通过防止 NIL 展开可选的行不通

Swift why unwrapping optional by guarding against NIL is not working

我是 Swift 的新手,但对可选展开的行为很好奇。

是否有任何解释为什么防止 != nil 不展开可选的?

举个简单的例子:

func hasC(_ s: String?) -> Bool {
  guard s != nil else {
    return false
  }

  return s!.contains("c")
}

我需要放置感叹号并显式展开值,尽管在最后一行似乎很清楚 s 不再是可选字符串。

我很想听听这种行为背后的原因,以及在这种情况下如何正确解包值?

创建额外的变量看起来很难看:

guard let s = s else { ... }

并且防止非布尔条件不起作用:

guard s else { ... }

回复:https://repl.it/@valerii/optional-unwrap

您没有使用 guard 声明新变量,函数参数是可选的,因此即使在 guard 语句之后它也允许您解包

func hasC(_ s: String?) -> Bool {
    if let containsValueInString  = s ,   containsValueInString.contains("c"){
         return true
    }
    return false

}

或者更简单,您可以使用带有 nil 合并运算符的可选链接

func hasC(_ s: String?) -> Bool {
  return  s?.contains("c") ?? false

}

s 的类型仍然是 Optional,因此您是否进行了 nil 检查是无关紧要的。 nil 检查在运行时完成,而类型系统正在执行编译时检查。确保 s 永远不会是 nil 的唯一方法是通过可选绑定 if letguard let.

guard 不会单独打开任何东西。这就像一种特殊的 ifguard let 展开,但它只是一个语法糖。

简单的答案是等号运算符,例如==!= 或任何比较运算符与从编译器的角度展开可选值无关。
guard 语句有 2 个一般用例。一种是防止 boolean 值,它是由等式或比较运算符生成的,如下例所示:

guard ["foo", "bar"].contains("foo") == true else { return }
guard 10 > 5 else { return }

guard 语句的另一个作用是解包可选值,它是用 guard letguard var 语法编写的。例如:

guard let unwrappedValue = anOptionalValue else { return }

该特定语法让编译器知道您正在尝试解包该值,如果解包成功,您将得到一个解包值。

当然,虽然创建另一个 variable/constant 可能看起来 "ugly",但这是进入 Swift 的方法。

您使用的格式有误

func hasC(_ s: String?) -> Bool {
  guard let input = s else {return false}

  return input.contains("c")
}

你可以这样做:

func hasC(_ s: String?) -> Bool {
  if let input = s {
  return input.contains("c")
  }
  return false
}

或者您可以像这样使输出可为空:

func hasC(_ s: String?) -> Bool? {
      return s?.contains("c")
}

func hasC(_ s: String?) -> Bool {
        return s?.contains("c") ?? false
}

不丑了。用较低的线。 最好的问候