标记未使用的块变量

saw*_*awa 11 ruby variables block

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

{[1, 2] => 3, [4, 5] => 6}.each{|(x, *), *| p x}

{[1, 2] => 3, [4, 5] => 6}.each{|(x, _), _| p x}

{[1, 2, 3], [4, 5, 6]}.each{|*, x, *| p x}

{[1, 2, 3], [4, 5, 6]}.each{|_, x, _| p x}

def (x, *), *; p x; end

def (x, _), _; p x; end

def *, x, *; p x; end

def _, x, _; p x; end
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*une 31

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

[[1, 2, 3], [4, 5, 6]].each{|*, x, *| p x}  # Syntax error
Run Code Online (Sandbox Code Playgroud)

实际上,Ruby应该如何知道第一颗恒星是否应该得到0,1或2的值(反之)?

在极少数情况下,您希望使用星号来忽略参数.例如,如果您只想使用可变数量的参数中的最后一个:

[[1], [2, 3], [4, 5, 6]].each{|*, last| p last}  # => prints 1, 3 and 6
Run Code Online (Sandbox Code Playgroud)

Ruby允许您不为参数的"其余"命名,但您可以使用_:

[[1], [2, 3], [4, 5, 6]].each{|*_, last| p last}  # => prints 1, 3 and 6
Run Code Online (Sandbox Code Playgroud)

通常,参数的数量是已知的,您最好的选择是使用_:

[[1, 2, 3], [4, 5, 6]].each{|_, mid, _| p mid}  # prints 2 and 5
Run Code Online (Sandbox Code Playgroud)

请注意,您也可以将最后一个参数保留为未命名(就像使用时一样*),尽管不太明显:

[[1, 2, 3], [4, 5, 6]].each{|_, mid, | p mid}  # prints 2 and 5
Run Code Online (Sandbox Code Playgroud)

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

  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
Run Code Online (Sandbox Code Playgroud)

第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
Run Code Online (Sandbox Code Playgroud)

最后,正如@DigitalRoss所说,_保留了最后的结果irb

更新:在Ruby 2.0中,您可以使用任何开头的变量_来表示它未被使用.这样,变量名称可以更明确地显示被忽略的内容:

_scheme, _domain, port, _url = parse_some_url
# ... do something with port
Run Code Online (Sandbox Code Playgroud)