* 表示“所有剩余参数”。 _ 只是另一个变量名,虽然它有点特殊。所以它们是不同的,例如以下没有意义:
[[1, 2, 3], [4, 5, 6]].each{|*, x, *| p x} # Syntax error
确实,Ruby 应该如何知道第一颗星应该获得 0、1 或 2 的值(反之亦然)?
在极少数情况下,您希望使用星号来忽略参数。例如,如果您只想使用可变数量的参数中的最后一个:
[[1], [2, 3], [4, 5, 6]].each{|*, last| p last} # => prints 1, 3 and 6
Ruby 允许您不给“其余”参数命名,但您可以使用_:
[[1], [2, 3], [4, 5, 6]].each{|*_, last| p last} # => prints 1, 3 and 6
通常,参数的数量是已知的,您最好的选择是使用_:
[[1, 2, 3], [4, 5, 6]].each{|_, mid, _| p mid} # prints 2 and 5
请注意,您也可以不命名最后一个参数(就像使用 * 时一样),尽管它不太明显:
[[1, 2, 3], [4, 5, 6]].each{|_, mid, | p mid} # prints 2 and 5
现在_ 是 指定的变量名称,当您不想使用某个值时要使用该名称。它是一个特殊的变量名有两个原因:
- 如果您不使用 Ruby(如果出现警告),Ruby 不会抱怨
- Ruby 将允许您在参数列表中重复它。
第 1 点示例:
> ruby -w -e "def foo; x = 42; end; foo"
-e:1: warning: assigned but unused variable - x
> ruby -w -e "def foo; _ = 42; end; foo"
no warning
第 2 点示例:
[[1, 2, 3], [4, 5, 6]].each{|unused, mid, unused| p mid}
# => SyntaxError: (irb):23: duplicated argument name
[[1, 2, 3], [4, 5, 6]].each{|_, mid, _| p mid}
# => prints 2 and 5
最后,正如@DigitalRoss 所说,_ 将最后一个结果保存在 irb 中
更新:在 Ruby 2.0 中,您可以使用任何以 _ 开头的变量来表示它未使用。这样,变量名称可以更明确地说明被忽略的内容:
_scheme, _domain, port, _url = parse_some_url
# ... do something with port