在if语句中评估可选对象的Bool属性

10

我正在寻找一种在单个 if 语句中简洁地评估 Swift Bool 的方法,当 Bool 是可选对象的属性时:

var objectWithBool: ClassWithBool?
// ...

if let obj = objectWithBool {
    if obj.bool {
        // bool == true
    } else {
        // bool == false
    }
} else {
    // objectWithBool == nil
}
有没有一种方法可以将这些if语句合并?在Objective-C中,这很容易实现,因为nil对象可以在同一表达式中进行评估。
if (objectWithBool.bool) {
    // bool == true
} else {
    // bool == false || objectWithBool == nil
}
3个回答

17

啊,找到了:

if objectWithBool?.bool == true {
    // objectWithBool != nil && bool == true
} else {
    // objectWithBool == nil || bool == false
}
可选链表达式objectWithBool?.bool返回一个可选的Bool。由于它是可选的,该表达式单独在if语句中会根据可选内容是否包含值而被评估为true/false
通过使用==运算符,if语句检查可选值,在这种情况下可选值可以是truefalsenil

我不会说它“强制评估可选的Bool”。objectWithBool?.bool可以是truefalsenil== Optional<Bool>.None),而比较== true仅在第一种情况下产生true - Martin R
1
@MartinR 是的,我有点草率了。我扩展了一下解释 - 希望现在更容易理解了。 - Stuart

4
另一个可能的解决方案是:
if objectWithBool?.bool ?? false {
    println("objectWithBool != nil && objectWithBool.bool == true")
} else {
    println("objectWithBool == nil || objectWithBool.bool == false")
}

"nil coalescing operator" a ?? b是一个简写形式,与以下代码等价:

a != nil ? a! : b

谢谢@MartinR。我喜欢空合并运算符,它可以产生一些非常整洁的代码。我认为,在这里使用它比使用“true”进行相等性检查略微不太清晰,因为乍一看,“false”的存在可能会让逻辑看起来相反。不过这是个好主意! - Stuart
@Stuart:这取决于你的看法。从(纯)C语言来看,我更喜欢使用if boolVar {}而不是if boolVar == true {},然后?? false作为默认值。对于其他类型也是类似的,例如if (myArray?.count ?? 0) > 0。所以这只是个人偏好的问题 :) - Martin R
你说得对,我也更喜欢在可能的情况下使用 if boolVar {}。我想我的意思是,从天真的角度来看,这可能会让人感到困惑,一眼看去可能会错误地认为表达式正在检查与 false 的相等性。当我更习惯阅读 ?? 运算符时,我可能会改变主意 :) - Stuart

0
你也可以这样做:
if let obj = objectWithBool where obj {
    // objectWithBool != nil && obj == true
} else {
   // objectWithBool == nil || obj == false
}

如果您需要在if块内部使用未包装的Bool,那么这将非常有用,否则您应该使用if let _ = objectWithBool ...来丢弃变量,或者使用其他答案之一。此外,请注意,在Swift 3中,语法已更改为if let obj = objectWithBool, obj { ... } else { ... } - Stuart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接