Shouldn’t it be Left Associative?
I think
let a = b ?? c ?? d
is grouped like
let a = (b ?? c) ?? d
not
let a = b ?? (c ?? d)
But it is declared as a Right Associative. Do I misunderstand or miss something?
Shouldn’t it be Left Associative?
I think
let a = b ?? c ?? d
is grouped like
let a = (b ?? c) ?? d
not
let a = b ?? (c ?? d)
But it is declared as a Right Associative. Do I misunderstand or miss something?
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.
f() ?? g() ?? h()
where f
may throw if g
is called first, etc. In this case, order does matter. –
Principality © 2022 - 2024 — McMap. All rights reserved.