julia迭代:开始,接下来,完成副作用

时间:2016-08-27 12:46:30

标签: julia

通过实现具有3个函数的迭代接口,可以为新定义的类型实现Julia中的迭代:startnextdone

我在这些函数的末尾看不到惊叹号,所以根据我对julia命名约定的理解,这3个函数不应该修改它们的参数。特别是这两个循环应该给出相同的输出

state = start(iter)
while !done(iter, state)
    (i, state) = next(iter, state)
    @show i
end


state = start(iter)
while !done(iter, state)
    (other_i, other_state) = next(iter, state)
    (i, state) = next(iter, state)
    @show i
end

我错了吗?我问,因为我在外部julia包中碰到了一些不尊重它的迭代器。

2 个答案:

答案 0 :(得分:7)

如果可能,那些函数不应该改变迭代器(这样可以复制和重用迭代器状态)。然而,有一些突出的例子表明这种设计是不可能的,或者只有在显着的性能损失下才有可能。这个例子的主要例子是Base.Task,它是可迭代的(每次迭代都运行到下一个produce语句):

julia> collect(@async for i = 1:10
       produce(i)
       end)
10-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10

在这些情况下,我们通常对变异很好(尽管当然任何使用迭代协议来缓存状态都不会起作用)。函数末尾的感叹号是一个约定,但不以任何方式强制执行(并不严格限制其输入参数的变异,而是具有一些副作用,您希望确保程序员知道)

答案 1 :(得分:3)

这些方法应该修改他们的参数,可能是因为您可能想要重复使用迭代器,并且您对感叹号标记是正确的。

你说得对,自定义是在方法名称修改参数时附加

我还遇到了一个包,ProgressMeter包使用了下一个方法!(),而且确实改变了你拥有的进度表类型

我喜欢感叹号的想法(我不知道它是否起源于朱莉娅或其他地方)但对于开发人员来说,确保其与此一致非常重要

<强> TL;博士 你是对的,它在文档中这么说,并且真正强调了这一点,详细描述它的部分称为Essentials

(请注意非英语母语人士,不存在感叹号)