词语产量的含义
目前我正在阅读David A. Black的“The Well-Grounded Rubyist”,我坚持10.9章(枚举器和可枚举的下一个维度)。 我的问题是关于yield
方法。 Ruby上下文中yield
这个词的含义是什么? 我的母语是俄语,谷歌翻译给我看了一堆翻译变体,让我感到困惑。 其中有一些: 给予 , 带来 , 投降 ( 放弃 ), 生产 , 同意 , 遵守和许多其他人。
UPD:请注意这个事实,我试图理解Enumerator :: Yielder#yield方法的含义,但不是yield
关键字本身。
UPD_2:我发现了有关枚举器的有趣文章:“ Ruby中的懒惰枚举器 ”。
单词yield在Ruby的上下文中并没有任何特殊含义。 它与其他编程语言或编程和计算机科学中的含义完全相同。
它通常在某种执行上下文放弃控制流到不同的执行上下文时使用。 例如,在Unix中,有一个sched_yield
函数,线程可以使用该函数将CPU放弃到另一个线程(或进程)。 对于协同程序,术语“ yield
通常用于将控制权从一个协程转移到另一个协程。 在C#中,有一个yield
关键字,迭代器方法使用它来放弃对迭代方法的控制。
实际上,这最后一个用法与Ruby中的Enumerator::Yielder#yield
方法的用法完全相同,您要问的是。 调用此方法将暂停枚举器并放弃对枚举方法的控制。
例:
fibs = Enumerator.new do |y| a, b = 0, 1 y.yield a loop do y.yield b a, b = b, a + b end end puts fibs.next # 0 puts fibs.next # 1 puts fibs.next # 1 puts fibs.next # 2 puts fibs.next # 3 puts fibs.next # 5 puts fibs.next # 8 puts fibs.next # 13 puts fibs.next # 21
如你所见,存在无限循环。 显然,如果这个循环只是单独运行,那就不会有多大用处。 但是因为每次碰到yield
方法,它都会放弃控制直到再次调用它,这将逐个产生Fibonacci数,基本上代表了所有Fibonacci数的无限长列表。
还有另一种方法Fiber.yield
,它具有类似的用途。 (事实上,我已在上面对其进行了描述,因为Fiber
只是Ruby的协同程序名称。)在Fiber
,您可以调用Fiber.yield
来放弃对最初控制给您的执行上下文的控制。
最后,有一个yield
关键字,它在方法体内部用于放弃对传递给方法的块的控制。
请注意,至少在Enumerator
情况下(即第一个示例),您还可以将yield
解释为生成 ,因为Enumerator
每次调用yield
都会生成一个新值。
在枚举器中屈服的背景下,意义最接近于“带来”。 Enumerator调用其yielder对象的yield方法,该方法“带出”传递给它的任何值。
give_me = Enumerator.new do |yielder| (1..5).each do |n| yielder.yield n end end 5.times do p give_me.next end
这导致:
1
2
3
4
五
在屈服于一个区块的情况下,意义最接近于“投降”。 带有yield语句的方法将执行放弃到传递给该方法的任何块。
def wage_war p "What should I do?" yield end wage_war { p "Surrender!" }
@Prostosuper,我最喜欢的相关定义就是这个 :
让步,放弃,给予(放弃;放弃或放弃对他人的物理控制)
在@Jamie Forrest的例子中,当调用wage_war时,“我该怎么办?” 首先打印,然后将流量控制产生 (承认,割让,授予,给予)给pay_war被调用的块,导致“投降!” 正在印刷。 该块完成后,流量控制将在wage_war中恢复。 如果在收益率之后还有另一个语句,那么在“投降”之后,当在wage_war中恢复流量控制时,它将被执行。 被打印了。
编辑 :@Prostosuper问及与枚举器有关的屈服,而不是块,我的例子讨论了它在块中的使用。 关于Enumerator :: Yielder#yield的SO问题(有答案)就在这里 。 定义的意义仍然适用。
您可能会发现阅读Programming Ruby 1.9对yield
关键字所说的内容很有趣:
编程语言增益程序很高兴知道选择关键字
yield
是为了回应Liskov语言CLU中的yield函数,这种语言已有三十多年的历史,但仍包含尚未被CLU广泛利用的特性 -减。
更多阅读:
CLU的历史 (pdf)
芭芭拉·利斯科夫 (维基百科)
yield,在ruby上下文中“带来”:)作为参数传递给您的方法的块。
def my_method p "I have to say something:" yield end my_method do p "hello world!" end
版画
I have to say something: hello world
当my_method达到yield时,执行代码p“hello world”