2016-07-25 162 views
1

是否有可能擁有內聯迭代器,它接受另一個內聯迭代器作爲參數?我的目標是做一個簡單的類似流水線的處理,並將其展開爲串行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

我創建了尼姆庫中的[問題](https://github.com/nim-lang/Nim/issues/4516)。這應該工作。 – flyx

回答

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) 
    

編輯:

的想法是使用一個模板,而不是一個內嵌迭代器,並注入代碼 - 所以沒有第二個迭代器,但一個模板。 也許這使得它更清晰:

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 
+0

我不確定我瞭解第二個選項。哪一部分代表'test2'迭代器? 'runIterator'不會產生任何東西。 – liori