为什么Swift三元运算符如此奇怪

时间:2018-02-27 20:07:20

标签: swift if-statement optional ternary-operator

假设我们有一个班级:

class Test: ExpressibleByNilLiteral {
    required init(nilLiteral: ()) {
    }

    init(_ text:String) {

    }
}

我们只想在某些条件 false

时创建实例
let condition = false

并使用此代码(1):

var test: Test? = condition ? Test("Z") : nil

根据我的理解,在其他语言和this reference中,上述代码等于:

var test: Test?
if condition {
    test = Test("Z")
}
else {
    test = nil
}

但实际上在第一种情况下我们得到的不是nil,而是Test类的非可选实例。换句话说,代码(1)实际上是这样的:

let test: Test? = condition ? Test("Z") : Test(nilLiteral: ())

此外,表达式(condition ? Test("Z") : nil)返回常规的非可选值,因此我们可以编写如下内容:

let test: Test = condition ? Test("Z") : nil

没有编译错误。

如果我们尝试没有ExpressibleByNilLiteral的类,我们会得到nil或编译错误,具体取决于变量类型,如预期的那样:

class Test2 {
    init(_ text:String) {

    }
}

let test2: Test2? = condition ? Test2("Z") : nil // test2 == nil
let test2: Test2 = condition ? Test2("Z") : nil // compilation error

更有趣的事情:

let test: Test = nil // non-optional instance initialized with nil
let test: Test? = nil // optional, nil

所以,问题是:为什么我们得到这个?

let test: Test? = nil // optional, nil
let test: Test? = false ? Test("Z") : nil // non-optional instance

这是使用SwiftyJSON的真实代码的第一个版本:

func checkResult(_ result: JSON) -> JSON? {
    return result["success"].stringValue == "true" ? result["result"] : nil
}

这是"修复"代码,按我的预期工作(如果成功则返回nil!= true):

func checkResult(_ result: JSON) -> JSON? {
    if result["success"].stringValue == "true" {
        return result["result"]
    }
    else {
        return nil
    }
}

稍后在程序中我使用

之类的东西
guard let result = checkResult(json) else { return }

第一个版本继续执行,如你所知,第二个 - 不要

0 个答案:

没有答案