为什么Nil合并运算符右关联?

Pit*_*ont 4 operators null-coalescing-operator associativity custom-operator swift

它不应该是左联想吗?

我觉得 let a = b ?? c ?? d 被分组像 let a = (b ?? c) ?? d let a = b ?? (c ?? d)

但它被宣布为右联盟.我误解或错过了什么吗?

Ant*_*nio 6

我认为这是一个优化.左或右关联不会改变结果.

这个:

(b ?? c) ?? d
Run Code Online (Sandbox Code Playgroud)

评估b ?? c,其结果用作左侧x ?? d.因此,即使b不为null,合并运算符也会执行2次.

在这种情况下

b ?? (c ?? d)
Run Code Online (Sandbox Code Playgroud)

如果b不是nil,则不评估右侧的表达式,因此不执行


附录

为了证明这一点,我做了一个简单的测试:我(重新)定义了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
}
Run Code Online (Sandbox Code Playgroud)

有了这个测试数据:

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

let d = a !!! b !!! c
Run Code Online (Sandbox Code Playgroud)

使用associativity left,这是打印到控制台的内容:

Optional("a")
Optional("a")
Run Code Online (Sandbox Code Playgroud)

而将关联性更改为right,输出为:

Optional("a")
Run Code Online (Sandbox Code Playgroud)

这意味着当使用右关联性时,如果左边不是nil,则忽略运算符的右侧.

  • 我不认为这是一个特殊的评估规则.它适用于左右相关性,但在后一种情况下,它的执行更加优化.查看更新的答案 (2认同)