最早看到yield时,就用c/C++中的概念对比了一番,发现最接近就是“宏代码的展开”。粗看起来,这样的理解是可以的。不过马上就有个问题出来了,就是定义域。宏代码的展开,要求展开后的代码处于被展开的位置同一个定义域,否则,相关变量和函数就会出现没有定义的错误。 不过从下面的ruby代码来看,yield没有这样的问题存在
class A
def self.test
yield
end
end
class B
def test0
puts "call from class B"
end
def test1
A.test {test0}
end
end
b = B.new
b.test1
如果以代码展开的角度来理解上面代码的运行,那么就应该出现test0 不是A的函数这样的错误提示。不过运行下来很成功,没有出现任何错误。
还有一种可能是ruby的函数调用,就像C++一样,默认附带一个this对象。
def test1
A.test {test0}
end
这段代码在执行时是不是被修改成了
def test1
A.test {@this.test0}
end
ruby如果真有这个功能,上面代码的执行似乎能够说的通。
不过上面都是猜测,看下《Programming Ruby - 2nd》第一次提到yield的时候得说明
引用
First, a block may appear only in the source adjacent to a method call; the block is written starting on the same line as the method call’s last parameter (or the closing parenthesis of the parameter list). Second, the code in the block is not executed at the time it is encountered. Instead, Ruby remembers the context in which the block appears (the local variables, the current object, and so on) and then enters the method. This is where the magic starts.
Within the method, the block may be invoked, almost as if it were a method itself, using the yield statement. Whenever a yield is executed, it invokes the code in the block.When the block exits, control picks back up immediately after the yield.1 Let’s start
with a trivial example.
def three_times
yield
yield
yield
end
three_times { puts "Hello" }
produces:
Hello
Hello
Hello
这段文字提到了3点。
第一,保存block相关的context
第二,block调用像函数本身的一部分
第三,有个神秘的control在操纵这一切
如果第一点,可以看作ruby给test0附加了个this对象,但是第二第三个就说不通了,如果只是代码展开,第二第三就不需要说明了。
看来关于yield是代码展开的想法是完全错的。
那么从第三点来看,yield的确有个代码运行块(先这样叫着)切换的动作,最后运行完了又切换回来.
加入代码切换的说法之后,给出的例子代码似乎是这样运行的
1.运行A.test的上半部分直到遇到yield
2.写入block的context,同时使用block的context和A.test运行到一半的context,作为block的运行环境来运行block代码,
3.block运行完毕,清除block的context,然后继续运行A.test的下半部分。
古怪阿古怪,yield是真的这样运行的吗?
从前面yield的翻译讨论来看,yield带有切换,退让,让步这类的意思。
yield如果有执行代码切换的功能,多少带有超级微型线程的意思了。而且是主动切换,执行代码主体。
yield完全是一个控制代码执行顺序的关键字了。真神奇。
分享到:
- 2006-10-31 08:57
- 浏览 13078
- 评论(31)
- 论坛回复 / 浏览 (31 / 30838)
- 查看更多
相关推荐
pkg yield yield是Riot.js v4的补充补丁,缺少在Riot.js v3使用<yield>实现的某些功能。 安装 对于npm用户, $ npm install @creatorqsf/yield 对于纱线使用者 $ yarn add @creatorqsf/yield 用法 在注册防暴...
任何@yield表达式可用于以:yield元数据注释的类,或者可用于所有扩展以:yield(Extend)注释的类的类。 @ :yield class MyClass { // ... } 以下示例显示了yield元数据的两种形式: @ yield return expression ; @...
本文实例讲述了Python yield的用法。分享给大家供大家参考,具体如下: yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法。 只是粗略的知道yield可以用来为一个函数返回值塞...
二、yield是一个语法糖,为方便开发者提供的一种方便方法 三、yield返回类型为IEnumerator、IEnumerable、IEnumerator、IEnumerable 四、如果返回类型为IEnumerator编译时会实现一个实现了IEnumerator接口的类 五、...
java 线程让步(Yield) java 线程让步(Yield) java 线程让步(Yield)
讲解Python的yield表达式,因为这个关键字平常不常用,也容易产生歧义,不易 理解;所以这里把它单独拿出来讲解,它与return的区别,它和生成器的关系,它的通常用法。
yield b #使用yield a, b =b, a + b n = n + 1 N = int (input("请输入生成行数N: ")) def yanghui_triangles(): a = [1] while True: yield a #执行到yield b 时,fab函数返回一个迭代值 a = [sum(i) for i ...
JS_Yield JS yield原始学习
本文实例讲述了Python 生成器,迭代,yield关键字,send()传参给yield语句操作。分享给大家供大家参考,具体如下: demo.py(生成器,yield关键字): # 生成器是一个特殊的迭代器。可以用for...in遍历。 # 带有...
本文实例讲述了C#中yield return用法,并且对比了使用yield return与不使用yield return的情况,以便读者更好的进行理解。具体如下: yield关键字用于遍历循环中,yield return用于返回IEnumerable,yield break用于...
初学 Python 的开发者经常会发现很多 Python 函数中用到了 yield 关键字,然而,带有 yield 的函数执行流程却和普通函数不一样,yield 到底用来做什么,为什么要设计 yield ?本文将由浅入深地讲解 yield 的概念和...
它最简单的调用形式看起来像一个return申明,不同之处在于普通return会返回值并终止函数的执行,而yield会返回一个值给循环调用此生成器的代码并且只是暂停执行生成器函数。 Example #1 一个简单的生成值的例子 <...
yield return <expression>; yield break; 备注: 计算表达式并以枚举数对象值的形式返回;expression 必须可以隐式转换为迭代器的 yield 类型。 yield 语句只能出现在 iterator 块中,该块可用作方法、运算符...
前言 最近在捣鼓Autobahn,它有给出个例子是基于asyncio 的,想着说放到pypy3上跑跑看竟然就……失败了...好吧这个标题是我google出来的,yield from的前世今生都在 这个PEP里面,总之大意是原本的yield语句只能将CPU控
使用C# yield关键字来提高性能和可读性
yield curve modelling, interest rate models
python库,解压后可用。 资源全名:ffmpeg_progress_yield-0.1.2-py2.py3-none-any.whl
AEC-Q002B1:2012 Guidelines for Statistical Yield Analysis - 完整英文电子版(6页).zip
yield生成器允许你 在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组。 使用示例: /** * 计算平方数列 * @param $start * @param $stop * @return Generator */ function squares($...
source code about yield curve