Checking the value of an Optional Bool

后端 未结 6 543
情书的邮戳
情书的邮戳 2021-01-30 10:13

When I want to check if an Optional Bool is true, doing this doesn\'t work:

var boolean : Bool? = false
if boolean{
}

It results in this error:

6条回答
  •  栀梦
    栀梦 (楼主)
    2021-01-30 10:31

    Optional binding

    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)'")
    }
    

    The code let booleanValue = booleanValue returns false if booleanValue is nil and the if block does not execute. If booleanValue is not nil, this code defines a new variable named booleanValue of type Bool (instead of an optional, Bool?).

    The Swift 3 & 4 code booleanValue (and Swift 2.2 code where booleanValue) evaluates the new booleanValue: Bool variable. If it is true, the if block executes with the newly defined booleanValue: Bool variable in scope (allowing the option to reference the bound value again within the if block).

    Note: It's a Swift convention to name the bound constant/variable the same as the optional constant/variable such as let booleanValue = booleanValue. This technique is called variable shadowing. You could break from convention and use something like let unwrappedBooleanValue = booleanValue, unwrappedBooleanValue. I point this out to help understand what's happening. I recommend using variable shadowing.

     

    Other Approaches

    Nil coalescing

    Nil coalescing is clear for this specific case

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

    Checking for false is not as clear

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

    Note: if !booleanValue ?? false does not compile.

     

    Force unwrapping optional (avoid)

    Force unwrapping increases the chance that someone will make a change in the future that compiles but crashes at runtime. Therefore, I would avoid something like this:

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

     

    A General Approach

    Though this stack overflow question asks specifically how to check if a Bool? is true within an if statement, it's helpful to identify a general approach whether checking for true, false or combining the unwrapped value with other expressions.

    As the expression gets more complicated, I find the optional binding approach more flexible and easier to understand than other approaches. Note that optional binding works with any optional type (Int?, String?, etc.).

提交回复
热议问题