nim語言默認是支持 for x in items 這樣的迭代的,而且一個類如果要支持迭代,可以用 yield 關鍵字,其實在 nim 主頁上第二個例子就已經重點介紹了。
# Thanks to Nim's 'iterator' and 'yield' constructs, # iterators are as easy to write as ordinary # functions. They are compiled to inline loops. iterator oddNumbers[Idx, T](a: array[Idx, T]): T = for x in a: if x mod 2 == 1: yield x for odd in oddNumbers([3, 6, 9, 12, 15, 18]): echo odd
但如果我的類希望像數組那樣直接被迭代,而不是要調用一個方法,怎麼辦? 事實上,nim 語言提供了語法糖,如果你迭代的對象包含一個 items 方法,且返回的是 iterator,那麼也可以的
# 讓其支持直接的 for 迭代訪問,默認情況下,如果 直接 for 一個變量,將默認調用他的items方法。 iterator items[E](this:SeqImmutableList[E]): E = for x in this.elements: yield x
這樣你就可以直接迭代了:
let target = newSeqImmutableList(@[1,2,3,4]) for x in target: echo x
完整代碼請參考:
type # 定義一個新的別名,用來統一對大數據結構的索引訪問。 idx = uint64 SeqImmutableList[E] = ref object elements : seq[E] # 爲 SeqImmutableList 定義了一個 size 屬性 proc size*[E](this: SeqImmutableList[E]) : idx {.inline.} = uint64(this.elements.len) #用到類型轉換 # 定義一個可以直接使用 [] 方式訪問的方法。 proc `[]`*[E](this: SeqImmutableList[E], index : idx) : E {.inline.} = this.elements[int(index)] # 讓其支持直接的 for 迭代訪問,默認情況下,如果 直接 for 一個變量,將默認調用他的items方法。 iterator items[E](this:SeqImmutableList[E]): E = for x in this.elements: yield x # 相當於構造函數,只有構造函數才能訪問私有變量。 proc newSeqImmutableList*[E](items : seq[E]) : SeqImmutableList[E] = new(result) result.elements = items let target = newSeqImmutableList(@[1,2,3,4]) echo "size = ", target.size echo "target[2] = ", target[2] for x in target: echo x