Checking the value of an Optional Bool

后端 未结 6 545
情书的邮戳
情书的邮戳 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:47

    As Antonio said

    Optionals no longer implicitly evaluate to true when they have a value and false when they do not, to avoid confusion when working with optional Bool values. Instead, make an explicit check against nil with the == or != operators to find out if an optional contains a value.

    I spent a few hours trying to understand a line of code I stumbled upon, but this thread put me on the right track.

    This quote is from august 2014, and since then Apple introduced Never following proposal SE-0102 and latter made it conform to Equatable, Hashable, Error and Comparable

    It is now possible to check if a boolean is nil using Never? :

    
    var boolean: Bool? = false
    boolean is Never? // false
    boolean = true
    boolean is Never? // false
    boolean = nil
    boolean is Never? // true
    
    

    You can actually use any other uninhabitable types :

    public enum NeverEver { }
    var boolean: Bool? = false
    boolean is NeverEver? // false
    boolean = true
    boolean is NeverEver? // false
    boolean = nil
    boolean is NeverEver? // true
    
    

    That being said, it's also possible to use a property wrapper now :

    @propertyWrapper struct OptionalBool {
        public var wrappedValue: Bool?
        public var projectedValue: Bool { wrappedValue ?? false }
        public init(wrappedValue: Bool?) {
            self.wrappedValue = wrappedValue
        }
    }
    
    struct Struct {
        @OptionalBool var predicate: Bool?
        var description: String {
            if $predicate {
                return "predicate is true"
            }
            return "predicate is false"
        }
    }
    
    var object = Struct()
    object.description // "predicate is false"
    object.predicate = false
    object.description // "predicate is false"
    object.predicate = true
    object.description // "predicate is true"
    
    

    or even:

    @propertyWrapper struct OptionalBool {
        var wrappedValue: Bool?
        var projectedValue: OptionalBool { self }
        var isNil: Bool { wrappedValue is Never? }
        var value: Bool { wrappedValue ?? false }
        
        init(wrappedValue: Bool?) {
            self.wrappedValue = wrappedValue
        }
    }
    
    struct Struct {
        @OptionalBool var predicate: Bool?
        var description: String {
            if $predicate.value {
                return "predicate is true"
            }
            if !$predicate.isNil {
                return "predicate is false"
            }
            return "predicate is nil"
        }
    }
    
    var object = Struct()
    object.description // "predicate is nil"
    object.predicate = false
    object.description // "predicate is false"
    object.predicate = true
    object.description // "predicate is true"
    
    

提交回复
热议问题