三元算子相关性

时间:2016-03-30 21:06:09

标签: swift operators ternary-operator associativity

我无法理解三元运算符中关联性的概念。在大多数情况下,三元运算符看起来像这样:

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 个答案:

答案 0 :(得分:2)

三元运算符始终是右关联的

三元运算符是右关联的,正如我们在你的第一个例子中看到的那样(正如我们在下面看到的,如果我们想让相应的if-else块包含除了以外的任何内容,这是我们唯一的选择。评估为布尔的表达式)。请注意,您的第二个示例没有留下任何房间关联性,因此这不会显示三元运算符的任何左关联性的示例。

/* 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 */

因此,即使嵌套三元运算符表达式,三元运算符的关联性也是明确定义的。但请注意,这样做往往会降低代码的可读性,甚至在Language Guide - Basic Operators

中也是完全建议的。
  

...

     

然而,请谨慎使用三元条件运算符。它的   如果过度使用,简洁会导致难以阅读的代码。 <强>避免   将三元条件运算符的多个实例组合成   一个复合语句。

三元运算符:不是两个一元运算符,而是它自己的唯一运算符

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

  
      
  • 一元运营商......

  •   
  • 二元运算符......

  •   
  • 三元运营商在三个目标上运营。像C一样,Swift只有一个三元运算符,即三元条件运算符(a?b:c)。

  •   

来自Language Guide - Basic Operators

由于我们只允许在Swift中自定义我们自己的prefix(一元)和infix(二元)运算符,我怀疑你将很难实现自己的 true 三元运算符,因为您只能将它用作两个单独的一元中缀运算符?:,这自然与单个三元运算符。 (您可以随时查看this somewhat old blog post by Nate Cook,解释如何使用两个二元运算符来模仿三元运算符,但是在Swift 3中要删除currying,我不知道这对于将来的Swift版本是否可行)。