它不应该是左联想吗?
我想
let a = b ?? c ?? d
被分组为
let a = (b ?? c) ?? d
不
let a = b ?? (c ?? d)
但它被宣布为右联盟。我是否误解或遗漏了什么?
答案 0 :(得分:6)
我认为这是一项优化。左或右关联不会改变结果。
此:
(b ?? c) ?? d
评估b ?? c
,其结果用作x ?? d
的左侧。因此,即使b
不为null,也会执行2次合并运算符。
在这种情况下改为
b ?? (c ?? d)
如果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
}
使用此测试数据:
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")
这意味着当使用右关联性时,如果左边不是nil,则忽略运算符的右侧。