Почему оператор слияния 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")

Это означает, что при использовании правой ассоциативности правая часть оператора игнорируется, если левая часть не равна нулю.

Другие вопросы по тегам