检查可选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
的代码如果booleanValue
是nil
并且if
块不执行if
返回false
。 如果booleanValue
不nil
,这段代码定义了一个名为booleanValue
的Bool
types的新variables(而不是可选的Bool?
)。
Swift 3&4代码booleanValue
(和Swift 2.2代码where booleanValue
)计算新的booleanValue: Bool
variables。 如果它是真的,则if
块使用新定义的booleanValue: Bool
variables(允许选项在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循环。