“产量”是什么意思? Ruby 中的关键字做什么?

发布于 2024-10-05 12:38:00 字数 236 浏览 7 评论 0原文

我遇到了以下 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

后来的我们 2024-10-12 12:38:01

当您编写采用块的方法时,可以使用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

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:

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

MyClass#each takes a block. It executes that block once for each item in the instance's items array, passing the current item as an argument.

It might be used like this:

instance = MyClass.new
instance.items = [1, 2, 3, 4, 5]
instance.each do |item|
  puts item
end
浅黛梨妆こ 2024-10-12 12:38:01

根据我的理解,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 进行调用

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 的值

这是一个游戏示例:

def load_game
    puts "Loading"

    yield

end


load_game { puts "Game loaded" }

这将在打印 loading 后立即打印 game returned

Loading

Game Loaded

According to my understanding yield executes code from block.

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}"}

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 is name {|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 of i.

Here is a game example for it:

def load_game
    puts "Loading"

    yield

end


load_game { puts "Game loaded" }

This will print game loaded right after printing loading:

Loading

Game Loaded

止于盛夏 2024-10-12 12:38:01

接收代码块的 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.

云雾 2024-10-12 12:38:01

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

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

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

hello do
    puts "there"
end 

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:

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

hello do
    puts "there"
end 

Output:

hello

there

world

蓝眼泪 2024-10-12 12:38:01

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 as return statement don't produces error.

return can only send single values where as Yield return object of huge values.

吾家有女初长成 2024-10-12 12:38:01

最终效果是,在 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.

溺深海 2024-10-12 12:38:01

正如 cpm 所说,它获取块并执行它

简单的例子:

def my_method
  yield
end


my_method do
  puts "Testing yield"
end

Testing yield
=> nil 

As cpm said its taking the block and executing it

Simple example:

def my_method
  yield
end


my_method do
  puts "Testing yield"
end

Testing yield
=> nil 
遮了一弯 2024-10-12 12:38:00

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

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[abcd]) 语句时初始化/创建的。

MyClass.each 方法中的 yield itemitem 传递到附加到 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 与块一起使用将迭代 @items 接收器,并在到达最后一项时停止,从而避免错误并保持良好和干净。

This is an example fleshing out your sample code:

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 loops over a collection. In this case it's looping over each item in the @items array, initialized/created when I did the new(%w[a b c d]) statement.

yield item in the MyClass.each method passes item to the block attached to my_class.each. The item being yielded is assigned to the local y.

Does that help?

Now, here's a bit more about how each works. Using the same class definition, here's some code:

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>'

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文