在swift中比较单个if结构中的非可选bool有什么问题

jsg*_*pil 5 mapper swift

我已经在Swift编写了一段时间,我想我必须放一个!我没有立即定义的所有let字段变量.

现在我注意到这段代码没有编译,我真的很惊讶?为什么是这样?

class MyClass : Mapper {
    var a: Bool!

    required init?(_ map: Map) {
    }

    // Mappable
    func mapping(map: Map) {
        a   <- map["a"]
    }
}

let myClass = MyClass()

if myClass.a { // Compiler not happy
    //  Optional type 'Bool!' cannot be used as a boolean; test for '!= nil' instead
}

if true && myClass.a { // Compiler happy

}

if myClass.a && myClass.a { // Compiler happy

}
Run Code Online (Sandbox Code Playgroud)

Apple Swift 2.2版

编辑
有些人指出为什么我使用一个let永远不会改变的变量.我提到它是用于字段变量,但我缩短了示例.使用ObjectMapper(http://github.com/Hearst-DD/ObjectMapper)时,init中不会立即定义所有字段.这就是为什么它们都是可选的?或要求!

vac*_*ama 1

一点历史...

在 Swift 1.0 中,只需检查以下内容optVar即可检查可选变量是否包含值:

if optVar {
    println("optVar has a value")
} else {
    println("optVar is nil")
}
Run Code Online (Sandbox Code Playgroud)

《Swift 编程语言》中,Swift 1.1 的更新(日期为 2014 年 10 月 16 日)指出:

可选值不再隐式评估true它们何时具有值以及false何时不具有值,以避免在使用可选Bool值时出现混淆。相反,nil使用==or!=运算符进行显式检查,以查明可选值是否包含值。

因此,您收到的无意义错误消息被放在那里,因为Swift编译器正在解释您的:

if a {
}
Run Code Online (Sandbox Code Playgroud)

意思是:

if a != nil {
}
Run Code Online (Sandbox Code Playgroud)

并且鼓励您进行测试nil以确定可选是否a具有值。

也许 Swift 作者将来会改变它,但现在你必须显式 unwrap a

if a! {
}
Run Code Online (Sandbox Code Playgroud)

或检查true

if a == true {
}
Run Code Online (Sandbox Code Playgroud)

或(为了完全安全):

if a ?? false {
    print("this will not crash if a is nil")
}
Run Code Online (Sandbox Code Playgroud)