dvl*_*lsg 18 php closures yield generator
我正在使用一个PHP类,它需要接受多种类型的迭代器并将它们包含在统一的包装器中.我需要支持的一种迭代器(并且可以!)是一个包含yield关键字的匿名函数 - 本质上是一个匿名生成器.
有没有办法在PHP中测试匿名函数是否是生成器?以下是我尝试过的方法列表(旨在显示输出,而不是我如何使用它们):
$anon = function() { yield 1; yield 2; }; // build anonymous generator
gettype($anon); // "object"
$anon instanceof \Traversable; // 0
$anon instanceof \Iterable; // 0
$anon instanceof \IteratorAggregate; // 0
$anon instanceof \Generator; // 0
$anon instanceof \Closure; // 1 -- but doesn't tell me whether or not the closure is actually generator
$anon = $anon(); // invoke, then run the same checks
gettype($anon); // "object"
$anon instanceof \Traversable; // 1 (!!!)
$anon instanceof \Iterable; // 0
$anon instanceof \IteratorAggregate; // 0
$anon instanceof \Generator; // 1 (!!!)
$anon instanceof \Closure; // 0
Run Code Online (Sandbox Code Playgroud)
正如您在上面所看到的,我可以调用匿名函数然后确定该函数是否是可遍历类型,但是为了以延迟加载的方式实现它(例如,围绕SQL语句调用的匿名函数包装器)然后是每个记录的产量),我不能在foreach迭代之前调用匿名函数.
是否有任何PHP方法/类型的我很想念,可用于确定哪些已经匿名方法是否不尚未调用是发电机?
Mar*_*ker 18
$anon = function() { echo 'INVOKED', PHP_EOL; yield 1; yield 2; };
$r = new ReflectionFunction($anon);
var_dump($r->isGenerator());
Run Code Online (Sandbox Code Playgroud)
节目
bool(true);
Run Code Online (Sandbox Code Playgroud)
INVOKED 根本不显示,证明在任何时候都不会调用闭包