为什么Ruby使用yield? [英] Why does Ruby use yield?

查看:77
本文介绍了为什么Ruby使用yield?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Ruby 的新手.我使用了很多允许高阶函数的 C# 和 JavaScript,我通常每天都在使用它们.

Ruby 对我来说似乎有点奇怪.each 函数可能如下所示:

定义每个@items.each 做 |item|产量(项目)结尾结尾items.each { |item|放置项目 }

然而,Ruby 也有一些对高阶函数的支持.上面的内容可以改写为:

def each(proc)@items.each 做 |item|过程调用项结尾结尾items.each ->(item) { puts item } # 或者...items.each lambda { |item|放置项目 }

甚至:

def each(&proc)@items.each 做 |item|过程调用项结尾结尾# 语法上没有区别.items.each { |item|放置项目 }

这与大多数其他语言更相似,而且只是长了几个字符.一切似乎都使用 yield,而不是显式地传入一个块.

yield 本身看起来很疯狂、神奇和神秘.毕竟,它会到达调用的起点并在调用之后立即抓取一个块.这看起来很奇怪和不自然,我不知道在另一种语言中有任何类似的功能.

那么 yield 是怎么回事?

解决方案

Yield Passes Objects to a Method's Block

<块引用>

[Yield is] 前往调用的起点并在调用后立即抓取一个块.

不是真的.yield 将参数传递给块;它不会抓住一个块"或用它做任何事情.换句话说,这是:

def foo;屈服自我;结尾foo { |x|x.检查}# =>主要的"

在这里,yield 没有做任何事情,只是将参数传递给传递给 foo 方法的块.每个 Ruby 方法都支持一个可选块——除非一个块实际上是强制性的——所以唯一的魔法"是该语言允许传递一个块,即使它没有明确声明为方法签名的一部分.

更多示例

要查看此隐式签名的实际效果,请考虑:

def foo;puts block_given?;结尾foo { |x|x.检查}

这将打印true"并返回 nil,这是 puts 方法的预期返回值.

当然,如果没有 yield,块就什么也做不了.例如:

def foo;结尾foo { |x|x.检查}# =>零

I am new to Ruby. I have used a lot of C# and JavaScript which allow higher-order functions and I typically use them on a daily basis.

Ruby seems a little strange to me though. An each function might look like:

def each
    @items.each do |item|
        yield(item)
    end
end

items.each { |item| puts item }

Yet Ruby also has some support for higher-order functions. The above could be rewritten to something like:

def each(proc)
    @items.each do |item|
        proc.call item
    end
end

items.each -> (item) { puts item }        # Or...
items.each lambda { |item| puts item }

Or even:

def each(&proc)
    @items.each do |item|
        proc.call item
    end
end

# No difference in syntax.
items.each { |item| puts item }

Which is more on par with most other languages, and is just a few characters longer. Instead of explicitly passing in a block, everything seems to use yield.

yield itself seems crazy, magical, and mysterious. After all, it's going to the origin of the call and grabbing a block immediately following the call. This seems bizarre and unnatural, and I'm not aware of any parallel of this feature in another language.

So what's the deal with yield?

解决方案

Yield Passes Objects to a Method's Block

[Yield is] going to the origin of the call and grabbing a block immediately following the call.

Not really. yield passes an argument to a block; it doesn't "grab a block" or do anything with it. In other words, this:

def foo; yield self; end
foo { |x| x.inspect }                                       
# => "main"

Here, yield isn't doing anything but passing an argument to the block that is passed into the foo method. Every Ruby method supports an optional block—except when a block is actually mandatory—so the only "magic" is that the language allows a block to be passed even when it isn't explicitly declared as part of the method signature.

Further Examples

To see this implicit signature in action, consider this:

def foo; puts block_given?; end
foo { |x| x.inspect }

which will print "true" and return nil, which is the expected return value from the puts method.

Of course, without yield the block doesn't do anything at all. For example:

def foo; end
foo { |x| x.inspect }
# => nil

这篇关于为什么Ruby使用yield?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆