37

有人可以向我解释 Ruby 在块中使用管道字符吗?我知道它包含一个变量名称,它将在迭代时分配数据。但这叫什么?管道内可以有多个变量吗?还有什么我应该知道的吗?有更多关于它的信息的好链接吗?

例如:

25.times { | i | puts i }
4

3 回答 3

32

大括号定义了一个匿名函数,称为块。管道之间的标记是这个块的参数。所需的参数数量取决于块的使用方式。每次评估块时,需要该块的方法将根据调用它的对象传递一个值。

它与定义方法相同,只是它不存储在接受块的方法之外。

例如:

def my_print(i) 
  puts i
end

执行时会做同样的事情:

{|i| puts i}

唯一的区别是块是动态定义的,而不是存储的。

示例 2:以下语句是等价的

25.times &method(:my_print)

25.times {|i| puts i}

我们使用匿名块是因为作为块传递的大多数函数通常特定于您的情况,不值得为重用而定义。

那么当一个方法接受一个块时会发生什么?这取决于方法。接受块的方法将通过以明确定义的方式从其调用对象传递值来调用它。返回的内容取决于需要该块的方法。

例如: In 25.times {|i| puts i}.times 为 0 和调用者的值之间的每个值调用一次块,将值作为临时变量 i 传递到块中。Times 返回调用对象的值。在这种情况下 25。

让我们看一下接受带有两个参数的块的方法。

{:key1 => "value1", :key2 => "value2"}.each {|key,value| 
     puts "This key is: #{key}. Its value is #{value}"
}

在这种情况下,每个键/值对都调用块,将键作为第一个参数,将值作为第二个参数。

于 2010-11-21T22:28:17.090 回答
5

管道指定由调用您的块的函数填充值的参数。它们可以有零个或多个,您应该使用多少个取决于您调用的方法。

例如,each_with_index 使用两个变量并将元素放在其中一个中,将索引放在另一个中。

这是对块和迭代器如何工作的很好的描述

于 2010-11-21T22:02:12.637 回答
2

块参数遵循与方法参数相同的所有约定(至少从 1.9 开始):您可以定义可选参数、可变长度参数列表、默认值等。这是一个相当不错的总结

需要注意的一些事情:因为块在它们定义的范围内看到变量,如果你传入一个与现有变量同名的参数,它将“隐藏”它 - 你的块将看到传入的值和原始变量将保持不变。

i = 10
25.times { | i | puts i }
puts i #=> prints '10'

最后将打印“10”。因为有时即使你没有传入一个值(即你想确保你不会意外地从周围范围中破坏一个变量),这也是可取的行为,你可以在参数列表后的分号后指定块局部变量名称:

x = 'foo'
25.times { | i ; x | puts i; x = 'bar' }
puts x #=> prints 'foo'

这里,'x' 是块的本地,即使没有传入任何值。

于 2010-11-21T22:27:02.173 回答