Julia迭代:开始,下一步,完成副作用



Julia可以通过实现具有3个函数的迭代接口来实现对新定义类型的迭代:start, next, done

我在这些函数的末尾没有看到感叹号,所以根据我对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包中碰到了一些不尊重这一点的迭代器。

如果可能的话,这些函数不应该改变迭代器的状态(这样迭代器的状态就可以被复制和重用)。然而,在一些突出的例子中,这样的设计是不可能的,或者只有在显著的性能损失下才可能实现。最典型的例子是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
在这些情况下,我们通常可以很好地处理突变(当然,任何使用缓存状态的迭代协议都不起作用)。函数末尾的感叹号是一种惯例,但不以任何方式强制执行(并且不严格限于其输入参数的突变,而是有一些您希望确保程序员意识到的副作用)。

这些方法应该不应该修改它们的参数,这可能是因为您可能想要重用迭代器,您关于感叹号标记的看法是正确的。

你是对的,习惯上是附加!如果方法修改了参数

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

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

tl;博士你说得对,文档里是这么说的,为了强调这一点,详细说明的部分叫做Essentials

(非英语为母语的人注意,没有感叹号这种东西)

相关内容

最新更新