You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Julia中for循环与列表推导式更新全局向量为何结果不同?

Julia全局向量历史存储问题解析

问题背景

存在全局向量vec需在循环中随机更新,全局向量vecvec(向量的向量)用于存储vec的历史版本:

  • 用make_vec()函数更新vec后推入vecvec,运行后vec每次循环更新符合预期,但vecvec中所有向量完全相同;
  • 改用make2_vec()或make3_vec()实现时,vecvec能正确保存vec的所有历史版本。

疑问解答

疑问1:为何vecvec中存储的历史向量全部一致?

你的猜测完全正确:Julia中的数组是可变引用类型。push!(vecvec, vec)操作并没有复制vec当前的数值内容,只是将指向该数组内存地址的引用添加到vecvec中。循环过程中,make_vec()始终在修改同一个数组的元素值,最终vecvec里的所有条目都指向同一个数组的最终状态,因此所有向量看起来完全一致。

疑问2:为何make2_vec()或make3_vec()能得到预期结果?

这两个函数的核心是每次都创建了新的数组实例:

  • make2_vec()中,[rand(0:9) for i=1:3]会直接生成一个全新的数组对象,随后将全局变量vec指向这个新数组的内存地址。每次循环推入vecvec的都是不同数组的引用,自然能保留每次更新的历史版本;
  • make3_vec()里先创建了局部数组vec3,修改其元素后再让全局vec指向它。每次循环都会生成一个新的vec3实例,本质也是每次向vecvec推入不同数组的引用,因此能正确保存所有历史状态。

可复现代码

vec = [1,2,3]
vecvec = []

function make_vec() 
    for i in 1:3
        vec[i] = rand(0:9)
    end
end

function make2_vec()
    global vec = [rand(0:9) for i=1:3]
end

function make3_vec()
    local vec3 = [1,2,3]
    for i in 1:3
        vec3[i] = rand(0:9)
    end
    global vec = vec3
end

    
for i in 1:5
    make_vec()     # make2_vec and make3_vec would give the desired result, but not make_vec
    println(vec)
    push!(vecvec,vec)
end

print(vecvec)

内容的提问来源于stack exchange,提问作者Alexander Kurz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 07:11:07