"if let" 语句执行,尽管值为 nil

"if let" statement executed despite value being nil

我有一个正在执行的 "if let" 语句,尽管 "let" 部分为零。

if let leftInc : Double? = self.analysis.inputs[self.btnLeftIncisor.dictionaryKey!]! {
    println(leftInc)
    let valueString : String = formatter.stringFromNumber(NSNumber(double: leftInc!))!
    self.leftIncisorTextField?.text = valueString
    self.btnLeftIncisor.associatedLabel?.text = valueString
}

// self.analysis.inputs is a Dictionary<String, Double?>

inputs 字典包含用户输入的信息 - 一个数字,如果他们还没有在匹配字段中输入任何内容,则为 nil。

在Swift之前的版本下,代码是这样写的:

if let leftInc : Double? = self.analysis.inputs[self.btnLeftIncisor.dictionaryKey!]?? {

并且工作正常。

我看到了一个类似的问题here,但在那个例子中,问题似乎是使用Any?的结果,但这里不是这种情况。

if-let 用于展开可选值。您通过将类型设置为可选的 Double 来允许 nil 值。

if 语句应该是:

if let leftInc = self.analysis.inputs[self.btnLeftIncisor.dictionaryKey!] as? Double{
...
}

这将尝试从输入中获取一个对象,如果失败则 returns nil 并跳过它。如果它执行 return 某些操作,它将尝试将其转换为 Double。如果失败,它也会跳过 if 语句。

如果输入是像 [Something:Double] 这样的字典,那么你不需要最后一个 as? Double 因为索引字典将 return 一个 Double?

我建议阅读 swift 关于可选链的书。

Swift 2.2

在你的 if let 中你定义了另一个可选的,这就是为什么 nil 是一个合法的案例。 if let 主要用于 从可选值中提取 (可能)非可选值。 你可以试试:

if let leftInc : Double = self.analysis.inputs[self.btnLeftIncisor.dictionaryKey!].flatMap ({[=10=]}) {
   // leftInc is not an optional in this scope
   ...
}

无论如何我会考虑不把它作为一个班轮来做,而是利用 guard 案例。只是为了增强可读性。并避免 bang 运算符 (!).

你可以进一步分解 -

if let optionalDouble = self.analysis.inputs[self.btnLeftIncisor.dictionaryKey!], leftInc = optionalDouble {
    ....
}

因为您的字典有可选值 - 这种书写方式可能会使发生的事情更清楚

if let k = dict["someKey"]{}, dict["someKey"] 将是 Any 类型的对象 这可以绕过 nill 因此,进行类型转换以使其正确,例如 if let k = dict["someKey"] as! String {}