PHP的Generator,也就是 yield/yield from 语法,使得函数调用可以“暂停”执行,并保留上下文,并在后续可以恢复执行。
但是,在PHP后续的设计中,很多地方都没有考虑到Generator:
Return Type Declarations(返回类型声明)
RFC见https://wiki.php.net/rfc/return_types。简而言之,可以给函数声明返回类型。先来看一段代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?php declare(strict_types=1);
function inner(): Iterator { yield __FUNCTION__; return 1; }
function gen(): Generator { yield __FUNCTION__; return yield from inner(); }
try { $gen = gen(); foreach ($gen as $yielded) { echo "yield: ".$yielded . PHP_EOL; } echo "return: " . $gen->getReturn() . PHP_EOL; } catch (Exception $e) { echo PHP_EOL; echo $e->getTraceAsString(); echo PHP_EOL; }
|
gen/inner函数是一个generator,yield的的类型是string,return的类型是int。但为了让PHP不报错,gen/inner函数的返回类型只能声明为Iterator或Generator——这完全破坏了返回类型声明的初衷:
对于普通函数,返回类型声明用来表示返回类型;对于generator,返回类型声明用来表示这是一个迭代器/Generator。(听着很不一致的样子)
好,没关系,无伤大雅。没法通过返回类型声明来推倒类型而已,我们通过PhpDoc来总可以了吧?
通过PhpDoc来标记返回类型
但是这个怎么写呢?对于刚刚的inner函数(yield的的类型是string,return的类型是int),最自然的写法是这样: