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

Jes*_*tny 2 ruby ruby-on-rails ternary-operator variable-assignment

这工作:

foo, bar = 1, 2
foo == 1  #true
bar == 2  #true
Run Code Online (Sandbox Code Playgroud)

这也有效:

baz = true
foo = baz ? 1 : 2
foo == 1  #true
Run Code Online (Sandbox Code Playgroud)

不起作用:

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

应如何格式化以使其有效?

Ama*_*dan 8

foo, bar = baz ? 1, 2 : 3, 4 <=这不起作用......为什么?

原因如下:

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

arg     : lhs '=' arg_rhs
        | # ...
        | arg '?' arg opt_nl ':' arg
        | # ...
Run Code Online (Sandbox Code Playgroud)

arg_rhs : arg
        # ...
Run Code Online (Sandbox Code Playgroud)

如上所述,任务lhs = rhs也是一个arg.但多项任务mlhs1, mlhs2 = mrhs1, mrhs2是一个声明:

stmt    : # ...
        | mlhs '=' mrhs_arg
        | # ...
        | expr
        ;
Run Code Online (Sandbox Code Playgroud)

虽然参数可以用作表达式

expr    : # ...
        | arg
        ;
Run Code Online (Sandbox Code Playgroud)

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

此外,当你有[1, 2],这是一个有效的数组,arg也是有效的arg_rhs,可以在右侧arg : lhs '=' arg_rhs.1, 2不是有效的arg,但它有效的mrhs_arg(多个建立的参数右侧,它或者具有多个逗号分隔的值等foo, bar = 1, 2,foo, bar = *[1, 2]或甚至foo, bar = 1, *[2],或destructures数组值等foo, bar = [1, 2]):

mrhs_arg : mrhs
         | arg_value
         ;

mrhs     : args ',' arg_value
         # ...
         | args ',' tSTAR arg_value
         # ...
         | tSTAR arg_value
         # ...
         ;
Run Code Online (Sandbox Code Playgroud)

所以它适合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:因为多个赋值的解析方式与简单赋值不同.


Jes*_*tny 7

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

foo, bar = baz ? [1, 2] : [3, 4]
Run Code Online (Sandbox Code Playgroud)

必须用括号括起true和false的返回值.

我希望这有帮助 :)

  • 这不能回答你的问题. (5认同)
  • 它回答(​​或提供解决方案)_"如何使用三元运算符进行多重赋值?"_ part. (3认同)