我遇到了以下 Ruby 代码:
class MyClass
attr_accessor :items
...
def each
@items.each{|item| yield item}
end
...
end
该each
方法有什么作用?特别是,我不明白是什么yield
。
我遇到了以下 Ruby 代码:
class MyClass
attr_accessor :items
...
def each
@items.each{|item| yield item}
end
...
end
该each
方法有什么作用?特别是,我不明白是什么yield
。
这是充实您的示例代码的示例:
class MyClass
attr_accessor :items
def initialize(ary=[])
@items = ary
end
def each
@items.each do |item|
yield item
end
end
end
my_class = MyClass.new(%w[a b c d])
my_class.each do |y|
puts y
end
# >> a
# >> b
# >> c
# >> d
each
循环一个集合。在这种情况下,它循环遍历@items
数组中的每个项目,在我执行new(%w[a b c d])
语句时初始化/创建。
yield item
在MyClass.each
方法中传递item
给附加到的块my_class.each
。被让出的item
被分配给本地y
。
这有帮助吗?
现在,这里有更多关于如何each
工作的信息。使用相同的类定义,这里有一些代码:
my_class = MyClass.new(%w[a b c d])
# This points to the `each` Enumerator/method of the @items array in your instance via
# the accessor you defined, not the method "each" you've defined.
my_class_iterator = my_class.items.each # => #<Enumerator: ["a", "b", "c", "d"]:each>
# get the next item on the array
my_class_iterator.next # => "a"
# get the next item on the array
my_class_iterator.next # => "b"
# get the next item on the array
my_class_iterator.next # => "c"
# get the next item on the array
my_class_iterator.next # => "d"
# get the next item on the array
my_class_iterator.next # =>
# ~> -:21:in `next': iteration reached an end (StopIteration)
# ~> from -:21:in `<main>'
请注意,在最后next
一个迭代器从数组的末尾掉了下来。这是不使用块的潜在陷阱,因为如果您不知道数组中有多少元素,您可能会要求太多项目并获得异常。
使用each
with 块将遍历@items
接收器并在它到达最后一个项目时停止,避免错误,并使事情保持整洁。
当你编写一个接受块的方法时,你可以使用yield
关键字来执行块。
例如,each
可以像这样在 Array 类中实现:
class Array
def each
i = 0
while i < self.size
yield( self[i] )
i = i + 1
end
end
end
MyClass#each
需要一个块。它为实例数组中的每个项目执行一次该块items
,并将当前项目作为参数传递。
它可以这样使用:
instance = MyClass.new
instance.items = [1, 2, 3, 4, 5]
instance.each do |item|
puts item
end
yield
接收代码块的 Ruby 方法通过使用关键字调用它来调用它。它可用于迭代列表,但它不像您在其他一些其他语言中找到的那样是迭代器。
这是一个很好的解释,比我能解释得更好。
根据我的理解,yield 从块中执行代码。
def name
puts "A yield will be called with id of 12"
yield 12
puts "A yield will be called with id of 14"
yield 14
end
name {|i| puts "I am called by yield name #{i}"}
输出:
将调用 id 为 12 的 yield
我被称为产量名称 12
将调用 id 为 14 的 yield
我被称为产量名称 14
产量如何运作?
因此,当name
函数在任何地方运行时,块代码都会运行。哪个是name {|i| puts "I am called by yield name #{i}"}
您可以看到有一个单词yield 12
yield 运行块内的代码,将 12 作为值传递i
。
这是一个游戏示例:
def load_game
puts "Loading"
yield
end
load_game { puts "Game loaded" }
这将在打印game loaded
后立即打印loading
:
正在加载
游戏加载
yield
告诉 ruby 调用传递给该方法的块,并为其提供参数。
yield
return
如果没有使用 as语句不会产生错误的块调用该方法,则会产生错误。
return
只能发送单个值作为Yield
巨大值的返回对象。
最终效果是在 MyClass 的实例上调用 .each 与在该实例的 .items 上调用 .each 相同。
作为一个新手,浏览许多答案让我感到困惑,直到我找到了 Abhi 的答案。
yield 命令暂停执行方法中的代码,而是将控制权交还给调用它的代码块,执行该代码,然后继续执行该方法的其余部分。这是一个为我澄清的示例:
def hello
puts "hello"
yield
puts "world"
end
hello do
puts "there"
end
输出:
你好
那里
世界
正如 cpm 所说的那样,它占用并执行它
简单的例子:
def my_method
yield
end
my_method do
puts "Testing yield"
end
Testing yield
=> nil