它不应该是左关联吗?
我认为
let a = b ?? c ?? d
分组
let a = (b ?? c) ?? d
不像
let a = b ?? (c ?? d)
但它被声明为右结合体。我是否误解或错过了什么?
它不应该是左关联吗?
我认为
let a = b ?? c ?? d
分组
let a = (b ?? c) ?? d
不像
let a = b ?? (c ?? d)
但它被声明为右结合体。我是否误解或错过了什么?
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.