gpt4 book ai didi

loops - 在 for 循环中,何时评估循环参数?

转载 作者:行者123 更新时间:2023-12-04 18:29:27 24 4
gpt4 key购买 nike

这是一个真正的初学者问题...

for循环,何时评估循环参数?

在这里,循环永远运行,所以 c显然每次循环开始时都会“被检查”:

c= [1]
for i in c
push!(c, i)
@show c
end
c = [1,1]
c = [1,1,1]
c = [1,1,1,1]
...

但是这个循环只被评估一次:
c= [1]
for i in 1:length(c)
push!(c, i)
@show c
end
c = [1,1]

这个看起来像是评估 enumerate(c)每个循环:
c= [1]
for (i, _) in enumerate(c)
push!(c, i)
@show c
end
c = [1,1]
c = [1,1,1]
c = [1,1,1,1]
...

但是这个循环显然不会:
c= [1]
for i in eachindex(c)
push!(c, i)
@show c
end
c = [1,1]

这确实:
c= [1]
foreach(a -> (push!(c, a); @show c), c)
c = [1,1]
c = [1,1,1]
c = [1,1,1,1]
...

正如我所说,这是一个真正的初学者问题。但是我是否缺少一般模式?

最佳答案

我相信重点是您的各种循环在两种不同类型的对象上调用 Julia 的迭代器接口(interface):

  • 数组对象 c本身
  • 一个 AbstractUnitRange对象(或其子类型之一)


  • 当您使用 for i in c 循环时, Julia 不知道有多大 c是。 Julia 需要的只是当前的迭代状态(它达到的索引)以及下一个要访问的索引 c应该。它可以测试它是否完成了对 c 的迭代。如果下一个索引会使它超出范围。

    从 Julia 的 iterator interface 复制文档,这样的循环基本上可以归结为:
    state = start(c)
    while !done(c, state)
    (i, state) = next(c, state)
    # body
    end

    如果您附加到 c在循环体中,总会有下一个要访问的索引(即 while !done(c, state) 将永远是 true )。数组 c可以增长,直到你的内存已满。

    使用 enumerate 的循环和 foreach 两者都依赖于数组 c 的迭代器接口(interface)以同样的方式,所以你在修改 c 时会看到类似的行为在这些循环中。

    另一方面,使用 for i in 1:length(c) 的循环和 for i in eachindex(c)不要迭代 c本身,但支持迭代器接口(interface)的不同对象。

    关键是这些对象是在迭代开始之前创建的,修改时不受影响 c在循环体中。

    在第一种情况下, length(c)计算然后 1:length(c)被创建为 UnitRange 的对象类型。在您的示例中,它从 1 开始并在 1 停止,所以我们 push!c在迭代期间只有一次。

    在第二种情况下,调用 eachindex([1])返回 Base.OneTo目的;就像 UnitRange对象,除非保证从 1 开始。在您的示例中 Base.OneTo(1)被创建并从 1 开始,也从 1 停止。

    这两个对象都是 AbstractUnitRange 的子类型。最终是 AbstractArray 的亚型.迭代器接口(interface)允许您按顺序访问这些对象所持有的值。

    关于loops - 在 for 循环中,何时评估循环参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41084855/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com