这有效:
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
# ^
如何对其进行格式化以使其有效?
答案 0 :(得分:8)
foo, bar = baz ? 1, 2 : 3, 4
< =这不起作用......为什么?
原因如下:
如果你看一下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
,可以放在{{1}的右侧}}。 arg : lhs '=' arg_rhs
不是有效的1, 2
,但 是有效的arg
(多个右侧构建的参数,其中包含多个以逗号分隔的值例如mrhs_arg
,foo, bar = 1, 2
或甚至foo, 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
中使用1}}规则。但是使用允许mrhs_arg : arg_value
(foo, bar = 1, 2
)的显式裸逗号的规则不能与条件一起使用,因为它明确要求至少两个以逗号分隔的参数 - 这不是条件的可能结果。
tl; dr:因为多次分配的解析方式与简单分配不同。
答案 1 :(得分:6)
以下是使用三元运算符进行多次赋值的正确语法:
foo, bar = baz ? [1, 2] : [3, 4]
true和false的返回值必须用括号括起来。
我希望这会有所帮助:)