如何在 Julia 中实现迭代器?

问题描述 投票:0回答:3

我正在尝试在 Julia 中实现迭代器,但是当 for 循环尝试调用

start
时出现异常。

这是我得到的(我运行了 include(...),然后

using RDF
):

julia> methods(start)
# 1 method for generic function "start":
start(graph::Graph) at /Users/jbaran/src/RDF.jl/src/RDF.jl:214

julia> for x in g
       println(x)
       end
ERROR: `start` has no method matching start(::Graph)
 in anonymous at no file

RDF
模块中的函数定义目前如下所示:

function start(graph::Graph)
    return GraphIterator(collect(keys(graph.statements)), nothing, nothing, nothing, [], [])
end

知道我做错了什么吗?

julia
3个回答
9
投票

在 Julia 1.+ 中,您应该实现:

  1. Base.iterate(::YourType)
    开始迭代,
  2. Base.iterate(::YourType, state)
    用于后续迭代,同时从前面的步骤中获取
    state

两种方法都应返回

(result, state)
元组,除了最后一次迭代应返回
nothing

实际上,这意味着用

 迭代 
x::YourType

for i in x
    # some code
end

是写作的简写

it = iterate(x)
while it !== nothing
    i, state = it
    # some code
    it = iterate(x, state)
end

详情请参阅手册


8
投票

不要忘记指定

Base.
- 您正在向现有函数添加方法。

module MyMod
  type Blah
    data
  end
  export Blah
  Base.start(b::Blah) = 1
  Base.done(b::Blah,state) = length(b.data) == state-1
  Base.next(b::Blah,state) = b.data[state], state+1
end
using MyMod
x = Blah([1,2,3])
for i in x
  println(i)
end

这在 Julia 0.3 中有效。


0
投票

基于@BoZenKhaa 的答案,一个常见的模式是

Base.iterate(yt::YourType, state=1) = state > length(yt) ? nothing : (yt.data[state],state+1)

其中

YourType
有一个字段
data
可以作为数组进行索引,
state
保存索引。 与
state=1
一起,右侧使用 三元运算符 来组合第 1+2 行,如果在末尾或者在该状态和下一个状态的元素元组的范围内,则返回
nothing

© www.soinside.com 2019 - 2024. All rights reserved.