"yield"关键字在Ruby中的作用是什么?

Mis*_*hko 32 ruby yield-keyword

我遇到了以下Ruby代码:

class MyClass
    attr_accessor :items
    ...
    def each
        @items.each{|item| yield item}
    end
    ...
end
Run Code Online (Sandbox Code Playgroud)

each方法有什么作用?特别是,我不明白是什么yield.

the*_*Man 31

这是一个充实示例代码的示例:

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
Run Code Online (Sandbox Code Playgroud)

each循环集合.在这种情况下,它循环遍历@items数组中的每个项目,在我执行new(%w[a b c d])语句时初始化/创建.

yield itemMyClass.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>'
Run Code Online (Sandbox Code Playgroud)

请注意,最后next迭代器从数组的末尾掉落.这是使用块的潜在缺陷,因为如果您不知道数组中有多少元素,您可以请求太多项并获得异常.

使用each一个块将迭代@items接收器并在它到达最后一个项目时停止,避免错误,并保持良好和干净.


cpm*_*cpm 15

当您编写一个接受块的方法时,您可以使用该yield关键字来执行该块.

作为一个例子,each可以在Array类中实现,如下所示:

class Array
  def each
    i = 0
    while i < self.size
      yield( self[i] )
      i = i + 1
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

MyClass#each需要一个块.它为实例的items数组中的每个项执行一次该块,将当前项作为参数传递.

它可能像这样使用:

instance = MyClass.new
instance.items = [1, 2, 3, 4, 5]
instance.each do |item|
  puts item
end
Run Code Online (Sandbox Code Playgroud)


Ger*_*ard 10

接收代码块的Ruby方法通过使用yield关键字调用它来调用它.它可以用于遍历列表,但它不是像其他语言中那样的迭代器.

是一个很好的解释,比我能够解释得更好.

  • fwiw - 我发现[本页](http://www.tutorialspoint.com/ruby/ruby_blocks.htm)给出{code} yield {code}的更简单的解释 (2认同)

小智 6

作为一个新手,浏览了许多答案让我感到困惑,直到我找到了 Abhi 的答案。

yield 命令暂停执行方法中的代码,而是将控制权传递回调用它的代码块,执行该代码,然后继续执行该方法的其余部分。这是一个为我澄清的例子:

def hello
    puts "hello"
    yield 
    puts "world"
end

hello do
    puts "there"
end 
Run Code Online (Sandbox Code Playgroud)

输出:

你好

那里

世界


Kal*_*lah 5

yield 告诉ruby调用传递给方法的块,给它参数.

yield如果没有使用块调用该方法,则会产生错误,其中as return语句不会产生错误.

return只能发送单个值作为Yield返回巨大值的对象.


Ily*_*rim 5

根据我的理解,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}"}
Run Code Online (Sandbox Code Playgroud)

输出:

将以id为12调用yield

我被产量名称12称为

将以id为14调用yield

我被产量名称14称为

产量如何?

因此,当name函数运行时,块代码会运行.这是name {|i| puts "I am called by yield name #{i}"}

你可以看到有一个单词yield 12yield运行块内的代码传递12作为值i.

这是一个游戏示例:

def load_game
    puts "Loading"

    yield

end


load_game { puts "Game loaded" }
Run Code Online (Sandbox Code Playgroud)

这将在打印game loaded后立即打印loading:

载入中

游戏加载