【问题标题】:Why is Nil coalescing operator Right Associative?为什么 Nil 合并运算符是右关联的?
【发布时间】:2014-12-10 09:12:30
【问题描述】:

不应该是左联想吗?

我认为 let a = b ?? c ?? d 被分组为 let a = (b ?? c) ?? d 不是 let a = b ?? (c ?? d)

但它被声明为右结合。我是否误解或遗漏了什么?

【问题讨论】:

    标签: swift operators null-coalescing-operator associativity custom-operator


    【解决方案1】:

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

    这个:

    (b ?? c) ?? d
    

    评估b ?? c,其结果用作x ?? d 的左侧。所以即使b不为null,合并运算符也会执行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")
    

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

    【讨论】:

    • 我认为在 ```` b ?? (c ?? d) ```` 应​​该在检查 b 是否为 nil 之前评估 (c ?? d?) 因为它们在括号中。因此,即使 b 不是 nil 但它们不是,也会评估这些表达式。
    • 但是我可以看到您对这些表达式的评估的观点,这是一个很好的观点。那么这是否意味着 Nil Coalescing 有一个特殊的评估规则?
    • 我不认为这是一个特殊的评估规则。它适用于左右关联,但在后一种情况下,它的执行更加优化。查看更新的答案
    • 哇,非常感谢。我忘了考虑@autoclosure。您的示例非常适合解释这一点。
    • 我使用了你的代码 sn-p 并删除了@autoclosure,结果和我预期的一样。
    猜你喜欢
    • 2017-11-03
    • 1970-01-01
    • 2011-11-16
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 2017-08-30
    • 2011-01-23
    相关资源
    最近更新 更多