【问题标题】:Getting return value of generator via iteration通过迭代获取生成器的返回值
【发布时间】:2019-09-02 18:36:39
【问题描述】:

我很难调和这两者:

const gen = function *() {
  yield 3;
  yield 4;
  return 5;
};

const rator = gen();

console.log(rator.next());  //  { value: 3, done: false }
console.log(rator.next());  //  { value: 4, done: false }
console.log(rator.next());  //  { value: 5, done: true }

上面我们看到了所有 3 个值,如果我们第四次调用 next(),我们得到:

{ value: undefined, done: true }

这是有道理的。但是现在如果我们在循环中使用它:

for(let v of gen()){
  console.log('next:', v); // next: 3, next: 4
}

我想我很困惑为什么使用 for 循环不打印 next: 5,但是手动调用迭代器上的 next() 可以获得 return 值。谁能解释这是为什么?

换句话说,我希望for loop 打印next: 5,但事实并非如此。

【问题讨论】:

  • 一旦done 为真,for 循环就结束了。返回值不是迭代序列的一部分。它通常是未定义的。
  • 正确,因此循环会丢弃第一个 done:true 对象附带的值。看起来很奇怪。

标签: javascript node.js generator coroutine


【解决方案1】:

为了保持一致性,这似乎可行?

const gen = function *() {
  yield 3;
  yield 4;
  return yield 5;
};

不过,return 关键字现在似乎没有任何作用。

【讨论】:

  • 这只会产生 5,然后在下一次迭代中返回 undefined。 done 在产生 5 时仍然为 false。您不妨删除 return -- 它是一样的。
【解决方案2】:

返回值包含在exception.value中,其中exception是生成器实例返回时生成器实例抛出的StopIteration。

例子:

def generator_function():
    yield 0
    yield 1
    return "text"

value_list = []
exception_list = []
try:
    a = generator_function()
    while True:
        value_list.append(next(a))
except StopIteration as e:
    exception_list.append(e)

print(value_list)
print(exception_list)
print(type(exception_list[0]), exception_list[0])
print(type(exception_list[0].value), exception_list[0].value)

另见Generator with return statement

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 2021-09-30
    • 1970-01-01
    相关资源
    最近更新 更多