检查可选Bool的值

当我想检查一个可选的布尔是否为真,这样做是行不通的:

var boolean : Bool? = false if boolean{ } 

它导致这个错误:

可选types“@IvalueBool?” 不能用作布尔值; testing'!= nil'代替

我不想检查零; 我想检查返回的值是否为真。

如果我正在使用可选Bool,那么我是否总是必须要做if boolean == true

由于Optionals不再符合BooleanType ,编译器不知道我想检查Bool的值吗?

使用可选的布尔值时,需要明确检查:

 if boolean == true { ... } 

否则,你可以打开可选的:

 if boolean! { ... } 

但是,如果布尔值nil ,则会生成运行时exception – 以防止:

 if boolean != nil && boolean! { ... } 

在testing版5之前,这是可能的,但是它已经在发行说明中报告了:

如果选项不具有值,则不会将其隐式评估为true,而在使用可选的Bool值时则不会造成混淆。 相反,使用==或!=运算符对nil进行显式检查,以确定可选是否包含值。

附录:根据@MartinR的build议,第三个选项的更简洁的变体是使用合并运算符:

 if boolean ?? false { ... } 

这意味着:如果布尔值不为零,则expression式求值为布尔值(即使用解包的布尔值),否则expression式计算结果为false

可选绑定

Swift 3&4

 var booleanValue : Bool? = false if let booleanValue = booleanValue, booleanValue { // Executes when booleanValue is not nil and true // A new constant "booleanValue: Bool" is defined and set print("bound booleanValue: '\(booleanValue)'") } 

Swift 2.2

 var booleanValue : Bool? = false if let booleanValue = booleanValue where booleanValue { // Executes when booleanValue is not nil and true // A new constant "booleanValue: Bool" is defined and set print("bound booleanValue: '\(booleanValue)'") } 

let booleanValue = booleanValue的代码如果booleanValuenil并且if块不执行if返回false 。 如果booleanValuenil ,这段代码定义了一个名为booleanValueBooltypes的新variables(而不是可选的Bool? )。

Swift 3&4代码booleanValue (和Swift 2.2代码where booleanValue )计算新的booleanValue: Boolvariables。 如果它是真的,则if块使用新定义的booleanValue: Boolvariables(允许选项在if块中再次引用绑定值)执行。

注意:这是一个Swift惯例,将绑定常量/variables命名为可选常量/variables,例如let booleanValue = booleanValue 。 这种技术被称为可变阴影 。 你可以打破常规,并使用let unwrappedBooleanValue = booleanValue, unwrappedBooleanValue 。 我指出了这一点,以帮助理解发生了什么。 我build议使用可变阴影。

其他方法

无合并

对于这个特定情况,无结合是明确的

 var booleanValue : Bool? = false if booleanValue ?? false { // executes when booleanValue is true print("optional booleanValue: '\(booleanValue)'") } 

检查false不是很清楚

 var booleanValue : Bool? = false if !(booleanValue ?? false) { // executes when booleanValue is false print("optional booleanValue: '\(booleanValue)'") } 

注意: if !booleanValue ?? false if !booleanValue ?? false不编译。

强制解包可选(避免)

强制解包增加了有人在将来编译但在运行时崩溃的机会。 因此,我会避免这样的事情:

 var booleanValue : Bool? = false if booleanValue != nil && booleanValue! { // executes when booleanValue is true print("optional booleanValue: '\(booleanValue)'") } 

一般方法

虽然这个堆栈溢出问题具体问如何检查Bool?if语句中是true的,那么确定检查true,false还是将展开的值与其他expression式结合起来的一般方法是有帮助的。

随着expression式变得更加复杂,我发现可选绑定方法比其他方法更灵活,更容易理解。 请注意,可选绑定适用于任何可选types( Int?String?等)。

我发现另一个解决scheme,重载布尔运算符。 例如:

 public func < <T: Comparable> (left: T?, right: T) -> Bool { if let left = left { return left < right } return false } 

这可能不完全符合语言变化的“精神”,但是它可以安全地解开可选项,并且可以用于任何地方的条件,包括while循环。