4

它不应该是左关联吗?

我认为 let a = b ?? c ?? d 分组 let a = (b ?? c) ?? d 不像 let a = b ?? (c ?? d)

但它被声明为右结合体。我是否误解或错过了什么?

4

1 回答 1

6

I think it's an optimization. Left or right association doesn't change the result.

This:

(b ?? c) ?? d

evaluates b ?? c, and its result is used as the left side of x ?? d. So even if b is not null, the coalescing operator is executed 2 times.

In this case instead

b ?? (c ?? d)

if b is not nil, the expression at the right side is not evaluated, hence not executed


Addendum

To prove that, I made a simple test: I (re)defined the nil coalescing operator:

infix operator !!! {
    associativity left
    precedence 110
}

func !!!<T>(optional: T?, defaultValue: @autoclosure () -> T?) -> T? {
    if let value = optional {
        println(optional)
        return value
    }

    let def = defaultValue()
    println(def)
    return def
}

With this test data:

let a: String? = "a"
let b: String? = "b"
let c: String? = "c"

let d = a !!! b !!! c

Using associativity left, this is what's printed to the console:

Optional("a")
Optional("a")

whereas changing the associativity to right, the output is:

Optional("a")

That means when using right associativity the right side of the operator is ignored if the left is not nil.

于 2014-10-15T10:40:06.027 回答