如何对三元运算符使用多重赋值?

How to use multiple assignment with a ternary operator?

这个有效:

foo, bar = 1, 2
foo == 1  #true
bar == 2  #true

这也有效:

baz = true
foo = baz ? 1 : 2
foo == 1  #true

这个工作:

foo, bar = baz ? 1, 2 : 3, 4
# SyntaxError: (irb):4: syntax error, unexpected ',', expecting ':'
# foo, bar = baz ? 1, 2 : 3, 4
#                    ^

如何格式化才能使其正常工作?

以下是使用三元运算符进行多重赋值的正确语法:

foo, bar = baz ? [1, 2] : [3, 4]

true 和 false 的 return 值必须括在方括号中。

希望对您有所帮助:)

foo, bar = baz ? 1, 2 : 3, 4 <= this DOES NOT work... why?

原因如下:

如果你查看parse.y(Ruby的语法),三元条件结构arg1 ? arg2 : arg3需要arg(一个参数)作为参数:

arg     : lhs '=' arg_rhs
        | # ...
        | arg '?' arg opt_nl ':' arg
        | # ...

arg_rhs : arg
        # ...

如上所示,赋值 lhs = rhs 也是一个 arg。但是多重赋值 mlhs1, mlhs2 = mrhs1, mrhs2 是一个 语句 :

stmt    : # ...
        | mlhs '=' mrhs_arg
        | # ...
        | expr
        ;

虽然参数可以用作表达式

expr    : # ...
        | arg
        ;

如上所示,表达式可以用作语句,反之则不然:语句并不总是有效的表达式,表达式也不总是有效的参数。

此外,当你有[1, 2]时,这是一个数组,它是一个有效的arg,也是一个有效的arg_rhs,它可以放在[的右侧=25=]。 1, 2 不是有效的 arg,但它 有效的 mrhs_arg(多个右侧由参数组成,其中有多个逗号- 分隔值,如 foo, bar = 1, 2foo, bar = *[1, 2] 甚至 foo, bar = 1, *[2],或解构数组值,如 foo, bar = [1, 2]):

mrhs_arg : mrhs
         | arg_value
         ;

mrhs     : args ',' arg_value
         # ...
         | args ',' tSTAR arg_value
         # ...
         | tSTAR arg_value
         # ...
         ;

所以它正好符合 stmt : mlhs '=' mrhs_arg 规则。

这最后一条规则也是您的解决方案 foo, bar = baz ? [1, 2] : [3, 4] 有效的原因:baz ? [1, 2] : [3, 4] 是一个 arg,也是 arg_value,并且可以在mrhs_arg : arg_value 规则。但是带有允许 foo, bar = 1, 2 (mrhs : args ',' arg_value) 的明确裸逗号的规则不能与条件一起使用,因为它明确要求至少两个逗号分隔的参数——这不是条件的可能结果。

tl;dr: 因为多重赋值的解析方式不同于简单赋值。