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)
应如何格式化以使其有效?
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:因为多个赋值的解析方式与简单赋值不同.
以下是使用三元运算符进行多次赋值的正确语法:
foo, bar = baz ? [1, 2] : [3, 4]
Run Code Online (Sandbox Code Playgroud)
必须用括号括起true和false的返回值.
我希望这有帮助 :)
| 归档时间: |
|
| 查看次数: |
1966 次 |
| 最近记录: |