如何在 Hack 中正确输入生成器函数

How to properly type a generator function in Hack

我正在尝试使用 Hack 并尝试使用 yield 关键字创建一个生成器函数。 documentation 指出这种函数的 return 类型应该是 Continuation 接口。但是,当 运行 hh_client 在生成器函数的源代码示例上时,我得到以下输出:

./test.php:4:3,7: Invalid yield (Typing[4110])
./test.php:3:17,28: This is an object of type Continuation
./test.php:4:3,7: It is incompatible with an object of type Generator (result of function with 'yield' in the body)

这是test.php:

<?hh

function gen(): Generator<int> {
  yield 1;
  yield 2;
  yield 3;
}

function foo(): void {
  foreach (gen() as $x) {
    echo $x, "\n";
  }
}

foo();

将结果类型更改为 Generator 会给出更多警告。生成器函数的正确输入方式是什么?

文档中任何提及 Continuation 的内容都是过时且错误的。有 an open issue about it.

正确的类型是Generator<Tk, Tv, Ts>——那里实际上有三个类型参数。以下是它们含义的示例:

$r = yield $k => $v;

该生成器的类型是 Generator<Tk, Tv, Ts>,其中 Tk$k 的类型,Tv$v 的类型,并且 Ts$r.

的类型

对于您的代码,这应该有效:

function gen(): Generator<int, int, void> {
  yield 1;
  yield 2;
  yield 3;
}

第一个int因为隐含了一个整数键;第二个 int 因为你正在 yielding int,而 void 因为你不关心将什么值发送到生成器。