问题描述
一个简单的问题.
何时或如何通过PHP或您自己来破坏生成器的堆栈?
When or how, by PHP or yourself do generators destroy their stacks?
以下面的示例为例:
function doWork(): Generator
{
// create some objects.
$o1 = new stdClass();
$o2 = new stdClass();
// pause here and wait for data.
$value = yield 1;
// By referencing the above objects, they shouldn't destruct.
$o1->property = $value;
$o2->property = $value;
yield $o1;
yield $o2;
// End of stack.
}
// Create the generator.
$generator = doWork();
$value = $generator->current(); // $value will equal 1.
if ($x) {
$generator->send('Hello, World!'); // Continue execution of the generator.
$o1 = $generator->current();
$generator->next();
$o2 = $generator->current();
$generator->next(); // Complete the generator
var_dump($o1);
var_dump($o2);
} else {
// Do nothing with the generator.
}
// Carry on with script ...
在此示例中,将启动生成器并创建两个对象.此时已产生,并要求进一步的数据.
In this example a generator is started and two objects are created. At this point it is yielded, and further data is requested.
到达IF语句.
案例1
如果$x
为true,则值"Hello, World!"
将发送到生成器,并且将使用其新属性填充对象.
If $x
is true, the value "Hello, World!"
will be sent to the generator and the objects will be populated with their new properties.
下次读取产生的数据时,将返回对象.
The next time the yielded data is read, the objects will be returned.
案例2
如果$x
为false,将不再使用生成器.
If $x
is false, the generator will no longer be used.
问题
在情况1中,我希望堆栈像其他任何函数一样关闭,但是在情况2中,生成器会发生什么?它和所有剩余的对象引用是否一直保留在内存中,直到脚本结束?
In case 1, I would expect the stack to close like any other function, but what happens to the generator in case 2? Does it and all of the remaining object references stay in memory until the script ends?
还是丢失对$generator
的引用会导致它,并且清除其中的所有引用?
Or does the loss of reference to $generator
cause it, and all references inside to be cleared out?
推荐答案
在两种情况下,生成器会破坏其执行上下文(还包括变量表):
There are two conditions under which a generator destroys its execution context (which also includes the variable table):
- 如果生成器完成执行.这可以通过执行
return
(包括在函数末尾的隐式返回)来实现,也可以通过在生成器执行期间遇到未捕获的异常来实现. - 如果放弃了对生成器对象的所有引用.
- If the generator finishes execution. This may either happen by executing a
return
(including the implicit return at the end of the function) or through an uncaught exception during execution of the generator. - If all references to the generator object are relinquished.
因此,不,在脚本结束之前,生成器将不存在.一旦$generator
变量超出范围,它将被销毁,此时生成器将放弃对变量值和其他执行状态的引用.
So, no, the generator will not live until the script ends. It will be destroyed once the $generator
variable goes out of scope, at which point the generator will relinquish its references to the variable values and other execution state.
通过在析构函数中创建echo
s的类,然后将该类实例化为局部变量,可以轻松地观察破坏顺序.
You can easily observe destruction order by creating a class that echo
s in the destructor and then instantiating this class into a local variable.
这篇关于PHP生成器-垃圾回收的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!