三目运算符的结合性

4

在三元运算符的上下文中,我对关联性的概念感到困惑。在大多数情况下,三元运算符看起来像这样:

a ? b : c

在这种情况下,评估表达式不需要结合性。但有时会嵌套三元运算符:
a ? b : c ? d : e
a ? b : (c ? d : e) // : is right-associative

然而,嵌套关系也可能被倒置。
a ? b ? c : d : e
a ? (b ? c : d) : e // : is left-associative

什么是最好的解释这种现象的方式?您是否考虑过:运算符的关联性取决于上下文,或者我在这里漏掉了什么?
当一个人想要定义自己的三元运算符时,例如在Swift中,关联性问题变得相关。
infix operator ? { associativity right precedence 120 }
infix operator : { associativity left precedence 130 }
1个回答

8

三元运算符始终是右结合的

如我们在您的第一个示例中所看到的那样,三元运算符是右结合的(正如我们下面所看到的,在这种情况下,如果要让相应的if-else块包含除bool值以外的任何其他内容,这是我们唯一的选择)。请注意,您的第二个示例不留下任何结合性,因此它并没有展示出任何左结合的三元运算符的示例。

/* example 1 */
a ? b : c ? d : e 
==> { right-ass. } => a ? b : (c ? d : e), OK
==> { left-ass. } => (a ? b : c) ? d : e
/*                        |___|
                             \ not OK: since then both of these must be 
                               booleans: that is restriction we don't have */

/* example 2 */ 
a ? b ? c : d : e
==> { only-valid-splitup } => a ? (b ? c : d) : e

(a ? b ? c) : d : e
/* |___|
      \ not valid, there's no ? ? ternary operator */

a ? b ? (c : d : e)
/*         |___|
              \ not valid, there's no : : ternary operator */

因此,即使嵌套三元运算符表达式,三元运算符的结合性也是明确定义的。但要注意,这样做可能会降低代码可读性,甚至是完全不推荐的,在语言指南-基本操作符中明确指出。

...

但是要小心使用三元条件运算符。如果过度使用,则其简洁性可能导致难以阅读的代码。避免将多个三元条件运算符实例组合成一个复合语句

三元运算符:不是两个一元运算符,而是一个独特的运算符

三元运算符是Swift中与其他运算符无直接关系的特殊运算符;所有其他运算符都属于一元和二元运算符族。

  • 一元运算符……

  • 二元运算符……

  • 三元运算符操作三个目标。像C语言一样,Swift只有一个三元运算符,即三元条件运算符(a?b:c)。

来自语言指南-基本操作符

由于在Swift中,我们只允许自定义自己的prefix(一元)和infix(二元)运算符,我怀疑您将很难实现自己的真正的三元运算符,因为您只能使用它作为两个单独的一元中缀运算符:,这自然不同于单个三元运算符。(您可以查看Nate Cook的这篇有点旧的博客文章,其中解释了如何通过使用两个二元运算符来模拟三元运算符,但由于Swift 3即将删除柯里化,我不知道这对未来的Swift版本是否可行。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接