Ternary Operator Associativity

混江龙づ霸主 提交于 2019-12-08 06:42:39

问题


I am having trouble understanding the concept of associativity in the context of ternary operators. In most cases, ternary operators look like this:

a ? b : c

In this case, no associativity is needed to evaluate the expression. Sometimes though, Ternary Operators are nested:

a ? b : c ? d : e
a ? b : (c ? d : e) // : is right-associative

However, the nesting could also be inverted

a ? b ? c : d : e
a ? (b ? c : d) : e // : is left-associative

What is the best way to explain this phenomenon? Could you consider the associativity of the : operator to be context-dependant, or am I missing something here?

The associativity question becomes relevant when one wants to define their own ternary operator, for example in Swift:

infix operator ? { associativity right precedence 120 }
infix operator : { associativity left precedence 130 }

回答1:


The ternary operator is always right-associative

The ternary operator is right-associative, as we see in your first example (and as we see below, this is the only choice we have if we want to let the corresponding if-else blocks to contain anything else than expressions that evaluate to booleans). Note that your second example leaves no room associativity, so this does it does not show an example of any left-associativity of the ternary operator.

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

Hence, the ternary operator's associativity is well-defined even if you nest ternary operator expressions. Take care, however, that doing so tends decrease code readability, and it is even outright recommended against this in the Language Guide - Basic Operators

...

Use the ternary conditional operator with care, however. Its conciseness can lead to hard-to-read code if overused. Avoid combining multiple instances of the ternary conditional operator into one compound statement.

The ternary operator: not two unary operators, but a unique operator of its own

The ternary operator is a special operator not really directly related to any of the other operators in Swift; all other belong to the families of unary and binary operators.

  • Unary operators ...

  • Binary operators ...

  • Ternary operators operate on three targets. Like C, Swift has only one ternary operator, the ternary conditional operator (a ? b : c).

From the Language Guide - Basic Operators.

Since we're only allowed to customly define our own prefix (unary) and infix (binary) operators in Swift, I suspect you will have quite difficult time implementing your own true ternary operator, since you're limited to using it as two separate unary infix operators ? and :, which is naturally not the same as a single ternary operator. (You could always look at this somewhat old blog post by Nate Cook, explaining how to mimic a ternary operator by using two binary operators, however as currying is to be removed in Swift 3, I don't know if this will be possible for future Swift versions).



来源:https://stackoverflow.com/questions/36319740/ternary-operator-associativity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!