Почему оператор слияния Nil является ассоциативным?
Разве это не должно быть левой ассоциацией?
Я думаю
let a = b ?? c ?? d
сгруппированы как
let a = (b ?? c) ?? d
не
let a = b ?? (c ?? d)
Но это объявлено как Правая Ассоциация. Я что-то неправильно понимаю или что-то упускаю?
1 ответ
Я думаю, что это оптимизация. Левая или правая ассоциация не меняет результат.
Это:
(b ?? c) ?? d
оценивает b ?? c
и его результат используется в качестве левой части x ?? d
, Так что даже если b
не равно нулю, оператор объединения выполняется 2 раза.
В этом случае вместо
b ?? (c ?? d)
если b
не ноль, выражение справа не вычисляется, следовательно, не выполняется
добавление
Чтобы доказать это, я сделал простой тест: я (пере) определил оператор слияния nil:
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
}
С этими данными теста:
let a: String? = "a"
let b: String? = "b"
let c: String? = "c"
let d = a !!! b !!! c
С помощью associativity left
вот что выводится на консоль:
Optional("a")
Optional("a")
в то время как изменение ассоциативности right
, вывод:
Optional("a")
Это означает, что при использовании правой ассоциативности правая часть оператора игнорируется, если левая часть не равна нулю.