“产量”是什么意思? Ruby 中的关键字做什么?
我遇到了以下 Ruby 代码:
class MyClass
attr_accessor :items
...
def each
@items.each{|item| yield item}
end
...
end
each
方法的作用是什么?特别是,我不明白 yield
的作用。
I encountered the following Ruby code:
class MyClass
attr_accessor :items
...
def each
@items.each{|item| yield item}
end
...
end
What does the each
method do? In particular, I don't understand what yield
does.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
当您编写采用块的方法时,可以使用
yield
关键字来执行该块。例如,
each
可以在 Array 类中实现,如下所示:MyClass#each
占用一个块。它为实例的items
数组中的每个项目执行该块一次,并将当前项目作为参数传递。它可能像这样使用:
When you write a method that takes a block, you can use the
yield
keyword to execute the block.As an example,
each
could have been implemented in the Array class like this:MyClass#each
takes a block. It executes that block once for each item in the instance'sitems
array, passing the current item as an argument.It might be used like this:
根据我的理解,yield 从块执行代码。
输出:
将使用 id 为 12 的yield 进行调用
I am call by yield name 12
将使用 id 为 14 的yield 进行调用
I am call byield name 14
yield 是如何工作的?
因此,当
name
函数在块代码运行的任何yield 出现的地方运行。这是name {|i| put "I am call by yield name #{i}"}
你可以看到有一个单词
yield 12
Yield 运行块内的代码,传递 12 作为i 的值
。这是一个游戏示例:
这将在打印
loading
后立即打印game returned
:Loading
Game Loaded
According to my understanding yield executes code from block.
Output:
A yield will be called with id of 12
I am called by yield name 12
A yield will be called with id of 14
I am called by yield name 14
How yield works?
So when the
name
function runs wherever yield comes the block code runs. Which isname {|i| puts "I am called by yield name #{i}"}
You can see that there is a word
yield 12
yield runs the code inside block passing 12 as value ofi
.Here is a game example for it:
This will print
game loaded
right after printingloading
:Loading
Game Loaded
接收代码块的 Ruby 方法通过使用
yield
关键字调用它来调用它。它可用于迭代列表,但它不是像其他语言中那样的迭代器。这里是一个很好的比我能更好地解释它的解释。
A Ruby method that receives a code block invokes it by calling it with the
yield
keyword. It can be used to iterate over a list but it is not a iterator like what you find in other some other languages.Here is a good explanation that explains it better than I would ever be able to.
作为一个新手,浏览了许多答案让我感到困惑,直到我找到了 Abhi 的答案。
yield 命令暂停执行方法中的代码,而是将控制权传递回调用它的代码块,执行该代码,然后继续执行该方法的其余部分。这是一个为我澄清的例子:
:
hello
world
输出
As a newbie, looking through a number of the answers confused me until I hit Abhi's answer.
the yield command pauses executing the code in the method, and instead passes control back to the block of code that called it, executes that code, and then continues executing the rest of the method after that. Here's an example that clarified it for me:
Output:
hello
there
world
yield
告诉 ruby 调用传递给该方法的块,并为其提供参数。如果未使用块调用该方法,则
yield
将产生错误,而return
语句不会产生错误。return
只能发送单个值,而Yield
返回大值对象。yield
tells ruby to call the block passed to the method, giving it its argument.yield
will produce an error if the method wasn't called with a block where asreturn
statement don't produces error.return
can only send single values where asYield
return object of huge values.最终效果是,在 MyClass 的实例上调用 .each 与在该实例的 .items 上调用 .each 相同。
The net effect is that calling .each on an instance of MyClass is the same as calling .each on the .items of that instance.
正如 cpm 所说,它获取块并执行它
简单的例子:
As cpm said its taking the block and executing it
Simple example:
这是充实示例代码的示例:
each
循环遍历集合。在本例中,它循环遍历@items
数组中的每个项目,这些项目是在我执行new(%w[abcd])
语句时初始化/创建的。MyClass.each
方法中的yield item
将item
传递到附加到my_class.each
的块。产生的item
被分配给本地y
。这有帮助吗?
现在,详细介绍一下
each
的工作原理。使用相同的类定义,下面是一些代码:请注意,在最后一个
next
上,迭代器脱离了数组的末尾。这是不使用块的潜在陷阱,因为如果您不知道数组中有多少元素,您可能会请求太多项目并得到异常。将
each
与块一起使用将迭代@items
接收器,并在到达最后一项时停止,从而避免错误并保持良好和干净。This is an example fleshing out your sample code:
each
loops over a collection. In this case it's looping over each item in the@items
array, initialized/created when I did thenew(%w[a b c d])
statement.yield item
in theMyClass.each
method passesitem
to the block attached tomy_class.each
. Theitem
being yielded is assigned to the localy
.Does that help?
Now, here's a bit more about how
each
works. Using the same class definition, here's some code:Notice that on the last
next
the iterator fell off the end of the array. This is the potential pitfall for NOT using a block because if you don't know how many elements are in the array you can ask for too many items and get an exception.Using
each
with a block will iterate over the@items
receiver and stop when it reaches the last item, avoiding the error, and keeping things nice and clean.