使用ruby splat运算符在哪里合法?
Splats很酷。 它们不只是用于爆炸arrays,尽管这很有趣。 它们还可以转换为数组并压平数组(请参阅http://github.com/mischa/splat/tree/master以获取他们所做的详尽列表。)
看起来无法对splat执行额外的操作,但在1.8.6 / 1.9中,以下代码抛出“意外的tSTAR”:
foo = bar || *zap #=> unexpected tSTAR
虽然这有效:
foo = *zap || bar #=> works, but of limited value
splat在表达式中出现在哪里?
首先,优先权不是问题,因为foo = bar || (*zap)
foo = bar || (*zap)
效果foo = bar || (*zap)
。 一般的经验法则是您无法在splat上执行其他操作。 即使是像foo = (*zap)
这样简单的东西也是无效的。 这也适用于1.9。
话虽如此,你期望foo = bar || *zap
foo = bar || *zap
如果有效,请执行,这与foo = bar || zap
foo = bar || zap
? 即使在像a, b = bar || *zap
的情况下a, b = bar || *zap
a, b = bar || *zap
(也不起作用), a, b = bar || zap
a, b = bar || zap
完成了我认为会是同样的事情。
这可能有意义的唯一情况是a, b = foo, bar || *zap
a, b = foo, bar || *zap
。 你会发现大多数你想要使用它的情况都包含在a, b = foo, *(bar || zap)
。 如果这不能涵盖你的情况,你应该问自己,你真正希望通过编写这样一个丑陋的结构来实现。
编辑:
在回复你的评论时, *zap || bar
*zap || bar
相当于*(zap || bar)
。 这表明了splat的优先级有多低。 究竟有多低? 我能给你的最好答案是“非常低”。
但是,对于一个有趣的例子,考虑一个带有三个参数的方法foo
:
def foo(a, b, c) #important stuff happens here! end
foo(*bar = [1, 2, 3])
将在赋值后展开,并将参数分别设置为1,2和3。 将其与foo((*bar = [1, 2, 3]))
,这将抱怨错误的参数数量(1为3)。
“splat运算符”实际上根本不是运算符,而是Ruby语法中定义的标记。 通读grammar.y或BNFforms的Ruby语法*会告诉您允许它作为最后一个或唯一的参数:
- 在方法定义中(可选的last
&foo
除外) - 在方法调用中(可选的last
&foo
除外) - 作为赋值的LHS,例如:
a, b, *cs = [1,2,3,4]
- 关于任务的RHS,例如:
a, b, c = 1, 2, *[3,4,5]
- 在案例陈述的when子句中