如何将多重赋值与三元运算符一起使用?
Posted
技术标签:
【中文标题】如何将多重赋值与三元运算符一起使用?【英文标题】:How to use multiple assignment with a ternary operator? 【发布时间】:2017-11-22 07:21:18 【问题描述】:这行得通:
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
# ^
应该如何格式化才能正常工作?
【问题讨论】:
当解析第三个表达式中的第一个逗号时,会引发异常"syntax error, unexpected ',', expecting ':'"
。那是因为1, 2
不是 Ruby 对象。
@AryaMcCarthy,好问题。我忘了包括错误响应。感谢编辑我的问题的人:)
另外,unexpected ','
很可能只是 Ruby 尽其所能识别缺陷。我在下面概述了更正的语法。
【参考方案1】:
下面是使用三元运算符进行多重赋值的正确语法:
foo, bar = baz ? [1, 2] : [3, 4]
true 和 false 的返回值必须用括号括起来。
我希望这会有所帮助:)
【讨论】:
这不能回答你的问题。 我同意,这个答案可能会解决原始问题(问题中没有描述),但它不是问题的答案。不知道它是如何获得赞成票的。 它回答(或提供解决方案)“如何使用三元运算符进行多重赋值?”部分。 我回答了我自己的问题。也许我应该更清楚。我并没有完全试图找出 whyfoo, bar = baz ? 1, 2 : 3, 4
不起作用,而是如何正确格式化语法以使用三元运算符进行多重赋值......为此,我相信它确实解决了问题。我认为最长最长的解释并不总是最好的答案。正如莎士比亚所说,“简洁是智慧的灵魂”。因此,我很乐意修改我的问题以排除“为什么?”为什么它会获得赞成票?因为它解决了如何的问题。【参考方案2】:
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
,它可以放在arg : lhs '=' arg_rhs
的右侧。 1, 2
不是一个有效的arg
,但它是一个有效的mrhs_arg
(多个右侧的参数组合,或者有多个逗号分隔的值,例如foo, bar = 1, 2
,@ 987654341@甚至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: 因为多重赋值的解析方式与简单赋值不同。
【讨论】:
以上是关于如何将多重赋值与三元运算符一起使用?的主要内容,如果未能解决你的问题,请参考以下文章