词语产量的含义

时间:2011-02-21 18:16:04

标签: ruby point yield enumerable

目前我正在阅读David A. Black撰写的“The Well-Grounded Rubyist”,我坚持10.9章(枚举数和可枚举的下一个维度)。我的问题是关于yield方法。 Ruby上下文中单词yield的含义是什么?我的母语是俄语,谷歌翻译向我展示了一堆翻译变体,让我感到困惑。其中有一些:带来投降放弃),生产同意遵守和其他许多人。

UPD:请注意,我正在尝试理解Enumerator::Yielder#yield方法的含义,而不是yield关键字本身。

UPD_2:我发现了有关枚举数的有趣文章:“Lazy Enumerators in Ruby”。

6 个答案:

答案 0 :(得分:18)

单词 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方法时,它都会放弃控制直到再次调用它,这将逐个产生斐波纳契数,基本上代表所有斐波纳契数的无限长列表。

还有另一种方法Fiber.yield,它有类似的用途。 (事实上​​,我已在上面对其进行了描述,因为Fiber只是Ruby的coroutines名称。)在Fiber内,你调用Fiber.yield放弃对最初执行上下文的控制权控制了你。

最后,有yield关键字,它在方法体内使用,以放弃对传递给方法的块的控制。

请注意,至少在Enumerator案例(即第一个示例)中,您可以另外将yield解释为以生成,因为Enumerator每次调用yield时都会生成一个新值。

答案 1 :(得分:3)

在枚举器中屈服的背景下,意义最接近于“带来”。 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
5个

在屈服于一个区块的情况下,意义最接近于“投降”。带有yield语句的方法将执行放弃到传递给该方法的任何块。

def wage_war
  p "What should I do?"
  yield
end

wage_war { p "Surrender!" }

答案 2 :(得分:2)

@Prostosuper,我最喜欢的相关定义是this one

  承认,放弃,给予(放弃;   放弃或放弃   物理控制另一个)

在@Jamie Forrest的例子中,当调用wage_war时,“我该怎么办?”首先打印,然后将流量控制产生(承认,割让,授予,给予)给pay_war被调用的块,导致“投降!”正在印刷。该块完成后,流量控制将在wage_war中恢复。如果在收益率之后还有另一个语句,那么在“投降”之后,当在wage_war中恢复流量控制时,它将被执行。印刷了。

编辑:@ Prostosuper询问与 枚举器 相关的产量,而不是块,我的示例讨论了它在块中的使用。关于Enumerator :: Yielder#yield的SO问题(有答案)是here。定义的意义仍然适用。

答案 3 :(得分:2)

您可能会发现阅读Programming Ruby 1.9对yield关键字所说的内容很有趣:

  

编程语言增益很高兴知道选择关键字yield来回应收益率   在Liskov的语言CLU中运行,这种语言已有三十多年的历史,但仍包含一些功能   没有被CLU-less广泛利用。

更多阅读:

A History of CLU(pdf)

Barbara Liskov(维基百科)

答案 4 :(得分:0)

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

代码p“hello world”在my_method达到yield

时执行

答案 5 :(得分:0)

在c#中,循环中的yield类似于return关键字,并且是迭代列表的循环的一部分。那为什么不使用return呢?因为使用yield可以在迭代该列表中的值时将控制权交还给循环。因此产量可能更像是一种控制机制。