嵌套的内联迭代器

时间:2016-07-25 21:09:13

标签: iterator nested nim

是否可以使用内联迭代器,它接受另一个内联迭代器作为参数?我的目标是进行简单的类似管道的处理,并将其展开为串行C代码。我无法开展工作的一个例子:

iterator test2(it: iterator(): int {.inline.}): int =
  for i in it():
    yield i*2
iterator test1(): int =
  yield 10
  yield 20
  yield 30
for i in test2(test1()):
  echo j

错误:

test.nim(2, 14) Error: type mismatch: got (int) but expected one of:
iterator items[IX, T](a: array[IX, T]): T
iterator items[](E: typedesc[enum]): E:type
iterator items(a: string): char
iterator items[T](s: Slice[T]): T
iterator items[T](a: openArray[T]): T
iterator items[T](a: seq[T]): T
iterator items[T](a: set[T]): T
iterator items(a: cstring): char
> Process terminated with exit code 256

1 个答案:

答案 0 :(得分:3)

你有2个选项(至少)

  1. 将您的迭代器定义为{.closure。}
  2. 使用模板来包装迭代器,这有点难看,但有效:

    template runIterator(it, exec: untyped): typed =
        block:
            it(myIterator)
            for i in myIterator() :
                exec(i*2)
    
    template defineTest1(name: untyped): typed =
    
        iterator `name`(): int {.inline.} =
            yield 10
            yield 20
            yield 30
    
    template defineTest2(name: untyped): typed =
    
        iterator `name`(): int {.inline.} =
            yield 5
            yield 10
            yield 15
    
    template exec(i: int): typed  = echo i
    
    runIterator(defineTest1, exec)
    runIterator(defineTest2, exec) 
    
  3. 编辑:

    这个想法是使用模板而不是内联迭代器并注入代码 - 因此没有第二个迭代器而是模板。 也许这会让它更清晰:

        template test2(it, yielder, exec: untyped): typed =
            for i in it() :
                let `yielder` {.inject.} = 2 * i
                exec
    
    
        iterator test1(): int {.inline.} =
            yield 10
            yield 20
            yield 30
    
        iterator test1b(): int {.inline.} =
            yield 5
            yield 10
            yield 15
    
        test2(test1, i):
            echo i
    
        test2(test1b, i):
            echo i