检查Optional Bool的值

问题描述 投票:70回答:3

当我想检查一个Optional Bool是否为true时,执行此操作不起作用:

var boolean : Bool? = false
if boolean{
}

它导致此错误:

可选类型'@IvalueBool?'不能用作布尔值;测试'!= nil'而不是

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

如果我正在使用Optional Bool,我是否总是要做if boolean == true

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

swift boolean optional
3个回答
167
投票

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

if boolean == true {
    ...
}

否则你可以解开可选的:

if boolean! {
    ...
}

但是如果boolean是nil,则会产生运行时异常 - 以防止:

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

在测试版5之前,它是可能的,但它已根据发行说明中的​​报告进行了更改:

Optionals在有值时不再隐式评估为true,而在没有值时则不再为false,以避免在使用可选的Bool值时出现混淆。相反,使用==或!=运算符对nil进行显式检查,以确定可选项是否包含值。

附录:正如@MartinR所建议的,第三种选择的更紧凑变体是使用合并运算符:

if boolean ?? false {
    // this code runs only if boolean == true
}

这意味着:如果boolean不是nil,则表达式求值为布尔值(即使用展开的布尔值),否则表达式求值为false


37
投票

Optional binding

斯威夫特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 = booleanValuefalse并且booleanValue块没有执行,则代码nil返回if。如果booleanValue不是nil,则此代码定义一个名为booleanValue的新变量Bool(而不是可选的Bool?)。

Swift 3&4代码booleanValue(和Swift 2.2代码where booleanValue)评估新的booleanValue: Bool变量。如果为真,则if块在范围内使用新定义的booleanValue: Bool变量执行(允许选项在if块内再次引用绑定值)。

注意:将绑定常量/变量命名为可选常量/变量(如let booleanValue = booleanValue)是一个Swift约定。这种技术称为变量阴影。你可以打破常规并使用像let unwrappedBooleanValue = booleanValue, unwrappedBooleanValue这样的东西。我指出这一点是为了帮助理解正在发生的事情。我建议使用变量阴影。

Other Approaches

没有合并

对于这种特定情况,没有合并是明确的

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不编译。

强制展开可选(避免)

强制解包会增加某人在未来编译但在运行时崩溃的可能性。因此,我会避免这样的事情:

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

A General Approach

虽然这个堆栈溢出问题具体询问如何在Bool?语句中检查true是否为if,但是确定检查true,false或将unwrapped值与其他表达式组合的一般方法是有帮助的。

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


-1
投票

我找到了另一个解决方案,重载了布尔运算符。例如:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.