【问题标题】:Iterator-producing function in Nim: works when assigning the iterator, stuck when calling it directlyNim 中的迭代器生成函数:分配迭代器时工作,直接调用时卡住
【发布时间】:2021-01-01 04:33:43
【问题描述】:

我尝试制作一个创建迭代器的过程,如下:

proc makeCDFrom(start: int): iterator(): int =
  result = iterator(): int =
    var
      i: int = start
    while i >= 0:
      echo "i:", i
      yield(i)
      dec(i)

let cdFrom6 = makeCDFrom(6)
for j in cdFrom6():
  echo "j:", j

这似乎按预期工作:

i:6
j:6
i:5
j:5
i:4
j:4
i:3
j:3
i:2
j:2
i:1
j:1
i:0
j:0

但是,最初,我尝试了这种细微的变化:

proc makeCDFrom(start: int): iterator(): int =
  result = iterator(): int =
    var
      i: int = start
    while i >= 0:
      echo "i:", i
      yield(i)
      dec(i)

# Note the direct call:
for j in makeCDFrom(6)():
  echo "j:", j

当我尝试在 https://play.nim-lang.org/ 上运行上述程序时,它似乎被卡住了。什么都没有显示。

为什么会有这种差异?

【问题讨论】:

    标签: while-loop iterator nim-lang


    【解决方案1】:

    为什么?

    因为有一个错误。

    你能做些什么呢?

    向 github.com/nim-lang/Nim 报告错误

    同时使用任一

    let myClosureIter = makeCDFrom(6)
    

    或者在没有工厂的情况下定义你的迭代器:

    iterator makeCDFrom(start: int): int =
        var
          i: int = start
        while i >= 0:
          echo "i:", i
          yield(i)
          dec(i)
    
    # Note the direct call:
    for j in makeCDFrom(6):
      echo "j:", j
    

    【讨论】:

    • 谢谢,我没想到会出现错误。对于初学者来说,奇怪的行为通常有非错误的解释。我在这里报道:github.com/nim-lang/Nim/issues/15339
    • @bli 可能是迭代器工厂不能这样使用,所以不应该编译。
    【解决方案2】:

    稍作改动:

    proc makeCDFrom(start: int): iterator(): int =
      echo "called again"
      result = iterator(): int =
        var
          i: int = start
        while i >= 0:
          echo "i:", i
          yield(i)
          dec(i)
    

    并且在本地运行,它处于无限循环中:

    called again
    i:6
    called again
    j:6
    called again
    i:6
    called again
    j:6
    called again
    i:6
    ...
    

    【讨论】:

    • 有趣。所以这似乎暗示for <variables> in <something> 语法在循环的每一步执行整个<something> 以获得<variables>。也就是说,我不明白为什么每个“周期”会执行 2 次 echo "called again"(正如 i:6j:6 的交替所暗示的那样)而不是 1 次。
    猜你喜欢
    • 2018-05-16
    • 2011-10-20
    • 2020-03-10
    • 2014-06-13
    • 2017-04-13
    • 2019-04-06
    • 2013-05-26
    • 1970-01-01
    • 2012-05-29
    相关资源
    最近更新 更多