标记未使用的块变量

当存在不使用的块或局部变量时,有时人们用*标记它,有时用_标记。

 {[1, 2] => 3, [4, 5] => 6}.each{|(x, *), *| px} {[1, 2] => 3, [4, 5] => 6}.each{|(x, _), _| px} {[1, 2, 3], [4, 5, 6]}.each{|*, x, *| px} {[1, 2, 3], [4, 5, 6]}.each{|_, x, _| px} def (x, *), *; px; end def (x, _), _; px; end def *, x, *; px; end def _, x, _; px; end 

他们之间有什么区别,我什么时候应该使用哪个? 当需要将多个变量标记为未使用时,如上例所示,是否更好?

A *表示“所有剩余参数”。 _只是另一个变量名,虽然它有点特殊。 所以它们是不同的,例如以下没有意义:

 [[1, 2, 3], [4, 5, 6]].each{|*, x, *| px} # 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 

现在_是您不想使用值时使用指定变量名。 它是一个特殊的变量名称,原因有两个:

  1. 如果您不使用Ruby,Ruby不会抱怨(如果警告已启用)
  2. 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 

我认为这主要是风格和程序员的选择。 在Ruby中使用*对我来说更有意义,因为它的目的是累积从该位置向前传递的所有参数。 _是一个在Ruby中很少见到的残留变量,我听说它需要消失。 所以,如果我要使用其中任何一个,我会使用*

有些公司可能会在他们的编程风格文档中定义它,如果他们有一个,但我怀疑它的大部分时间是值得的,因为它是一个丢失的变量。 我已经专业开发了20多年,并且从未见过任何定义扔掉命名的东西。

就个人而言,我并不担心这一点,我更关心单字母变量的使用。 为此,我会使用unusedvoidblackhole

IMO这种做法使代码的可读性降低,而且不那么明显。

特别是在采用块的API方法中,可能不清楚块实际期望什么。 这故意从源中删除信息,使维护和修改更加困难。

我宁愿变量被恰当地命名; 在短暂的区块中,很明显它没有被使用。 在较长的区块中,如果非使用是显着的,评论可能会详细说明原因。

它们之间有什么区别?

_ case中,正在创建局部变量_ 这就像使用x但命名不同。

*情况下,将表达式赋值给*创建[expression] 我不太确定它有什么用处,因为它似乎没有做任何用括号括起来的表达式。

我什么时候应该使用哪个?

在第二种情况下,您最终不会创建额外的符号,但对于解释器来说,它看起来稍微有些工作。 此外,很明显你永远不会使用那个结果,而使用_ ,必须阅读循环以了解它是否被使用。

但我预测你的代码质量将取决于你用来摆脱未使用的块参数的技巧。 *确实有一些我不喜欢的模糊的酷因子。

注意:在尝试此操作时,请注意在irb中, _保存最后一个表达式的值。