- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
$val-6ren">
我最近偶然发现了这段代码:
function xrange($min, $max)
{
for ($i = $min; $i <= $max; $i++) {
yield $i;
}
}
我以前从未见过这个 yield
关键字。尝试运行我得到的代码
Parse error: syntax error, unexpected T_VARIABLE on line x
那么这个 yield
关键字是什么?它甚至是有效的PHP吗?如果是,我该如何使用它?
最佳答案
yield
?yield
关键字returns data from a generator function:
The heart of a generator function is the yield keyword. In its simplest form, a yield statement looks much like a return statement, except that instead of stopping execution of the function and returning, yield instead provides a value to the code looping over the generator and pauses execution of the generator function.
生成器函数实际上是编写 Iterator 的更紧凑和更有效的方法。 .它允许您定义一个函数(您的 xrange
),该函数将计算并返回 值 您是 looping over it :
function xrange($min, $max) {
for ($i = $min; $i <= $max; $i++) {
yield $i;
}
}
[…]
foreach (xrange(1, 10) as $key => $value) {
echo "$key => $value", PHP_EOL;
}
这将创建以下输出:
0 => 1
1 => 2
…
9 => 10
你也可以通过使用
来控制foreach
中的
$key
yield $someKey => $someValue;
在生成器函数中,$someKey
是您希望出现的任何 $key
和 $someValue
是 $ 中的值值
。在问题的例子中是 $i
.
现在您可能想知道为什么我们不简单地使用 PHP 的原生 range
function以实现该输出。你是对的。输出将是相同的。不同之处在于我们如何到达那里。
当我们使用 range
PHP 时,会执行它,在内存中创建整个数字数组,然后 return
那个 整个数组 到 foreach
循环,然后将遍历它并输出值。换句话说,foreach
将对数组本身进行操作。 range
函数和 foreach
只“交谈”一次。把它想象成在邮件中收到一个包裹。送货员会把包裹递给你然后离开。然后你打开整个包裹,取出里面的任何东西。
当我们使用生成器函数时,PHP 会单步执行该函数,直到它遇到结束或 yield
关键字。当它遇到 yield
时,它会将当时的值返回到外部循环。然后它回到生成器函数并从它产生的地方继续。由于您的 xrange
包含一个 for
循环,因此它将执行并产生直到达到 $max
为止。把它想象成 foreach
和生成器打乒乓球。
显然,生成器可用于解决内存限制。根据您的环境,执行 range(1, 1000000)
将使您的脚本致命,而使用生成器同样可以正常工作。或者正如维基百科所说:
Because generators compute their yielded values only on demand, they are useful for representing sequences that would be expensive or impossible to compute at once. These include e.g. infinite sequences and live data streams.
生成器也应该很快。但请记住,当我们谈论快速时,我们通常会谈论非常少的数字。因此,在您现在运行并更改所有代码以使用生成器之前,请先做一个基准测试,看看它在哪里有意义。
生成器的另一个用例是异步协程。 yield
关键字不仅返回值,而且还接受它们。有关这方面的详细信息,请参阅下面链接的两篇优秀的博客文章。
yield
?PHP 5.5 中引入了生成器。尝试在该版本之前使用 yield
会导致各种解析错误,具体取决于关键字后面的代码。因此,如果您从该代码中收到解析错误,请更新您的 PHP。
关于php - PHP 中的产量是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17483806/
使用 Python 3.4,我在此处得到 SyntaxError: invalid syntax: >>> xlist = [1,2,3,4,5] >>> [yield(x) for x in xli
在这篇文章 ( http://blogs.msdn.com/oldnewthing/archive/2008/08/13/8854601.aspx ) 中,有一个关于迭代器的流行问题和一个关于极端情况
在 Ruby 中,yield 关键字用于让出执行 block 的闭包。 这个关键字在 Python 语言中有何不同? 最佳答案 在 ruby 中,yield 是用于调用匿名函数的快捷方式。 Rub
这个问题在这里已经有了答案: check if function is a generator (13 个答案) 关闭 7 年前。 检查函数是否为生成器的可靠方法是什么,例如: let fn = f
jquery 中是否可以产生变量?我想在部分 View 中设置一个变量,根据该变量我将某个菜单项设置为事件状态。 我有一个菜单,我想在其中产生像这样的事件项目(在我的主布局 View 中): func
问题 是否可以将 yielding pytest fixtures(用于设置和拆卸)作为参数传递给测试函数? 上下文 我正在测试一个对象,该对象从单个目录中的文件读取数据/向文件写入数据。该目录的路径
我刚刚开始使用 Ruby,我在 Bloc 的类(class)中已经走了很长一段路,但现在我被困在与 yield 和 blocks 有关的练习上(我发现这是迄今为止最难掌握的概念说到学习 ruby
我一直在寻找这一点,但我还没有得到任何关于它的信息!。 我看了很多关于“ yield 返回”的视频和红色文章,我想我对它有更好的理解,但有一点我无法理解 我应该使用 yield return 的正确接
UPDATE(反映最先进的知识水平)状态:2017-05-12 进行此更新的原因是,当我问这个问题时,我并不知道我发现了有关Python3如何“在幕后”工作的信息。 从所有得出的结论是: 如果您为迭代
我正在尝试在 Atmel Studio 7 中为 Arduino 编写代码。为了使其与 Arduino IDE 相似,我正在尝试调整其库。 但是我已经被 delay() 阻止了,它使用了 yield(
我正在构建一个简单的 C++ 服务器,我在其中通过 POST 请求接收图像,将其发送到 GPU 进行处理,一旦我从 GPU 获得结果,就发回响应。 为了能够处理许多同时连接(并学习新的东西),我正在使
我想生成从每片叶子到树根的所有路径。我想用生成器来做,以节省内存(树可以很大)。这是我的代码: def paths(self, acc=[]): if self.is_leaf():
假设我有以下代码(缩小上下文以限制问题范围) public static IEnumerable GetThemColors(){ var ids = GetThePrimaryIds();
我想我也有同样的问题。 Using multiple yields to insert content 我尝试了这个解决方案。我试过 在我的 application.html.erb 中有 conte
我熟悉 yield 以返回值,这主要归功于 this question 但是当它在赋值的右边时,yield 会做什么呢? @coroutine def protocol(target=None):
function * d1 (p) { p-=1; yield p; p-=2; yield p; } var g=d1 (9); var h; console.l
以下代码在 golang 中实现了 yield 模式。作为一项实验,我正在实现一个all permutations 生成器。但是,当我将 slice A 返回到 channel 时,如果我不创建数组的
Node.js 现在有生成器。 我的理解是,生成器可用于编写看起来更加线性的代码,并避免回调 hell 和末日风格编码的金字塔。 所以到目前为止,我的理解是,在生成器内部,代码会一直执行,直到它到达“
我遇到的问题真的很奇怪。由于某种原因,我的 catch block 中的 put 没有在下面执行。这是我的传奇: function* postLoginFormSaga(action) { l
假设我只想快速使以下方法异步运行: ResultType SynchronousCode(ParamType x) { return SomeLongRunningWebRequest(x)
我是一名优秀的程序员,十分优秀!