我对Julia 1.0.3处理全局变量的方式感到有些困惑。有没有一种方法可以使用!push来更新全局数组?
在REPL中玩游戏时,我想更新一个全局变量,然后将结果push!
到一个全局数组中进行存储。
var = [1]
res = []
for i in 1:5
global var
global res
push!(var,i)
print(string(var,"\n"))
push!(res,var)
end
但是,存储在res
中的值如下:
[1, 1, 2, 3, 4, 5]
[1, 1, 2, 3, 4, 5]
[1, 1, 2, 3, 4, 5]
[1, 1, 2, 3, 4, 5]
[1, 1, 2, 3, 4, 5]
我希望这样:
[1, 1]
[1, 1, 2]
[1, 1, 2, 3]
[1, 1, 2, 3, 4]
[1, 1, 2, 3, 4, 5]
特别令人费解的是,行为似乎是变量而不是数组的预期结果:
var = 1
res = []
for i in 1:5
global var
global res
var = var + i
print(string(var,"\n"))
push!(res, var)
end
给出预期结果的地方
2
4
7
11
16
我显然错过了一些东西。
答案 0 :(得分:2)
您正在将相同的var
数组推入res
数组中的每个位置。例如:
julia> var = [1]
1-element Array{Int64,1}:
1
julia> res = [var, var]
2-element Array{Array{Int64,1},1}:
[1]
[1]
julia> var[1] = 2
2
julia> res
2-element Array{Array{Int64,1},1}:
[2]
[2]
res
数组中的两个元素都是 var
本身。因此,如果您修改var
(使用push!
或索引分配等方式),那么无论您如何访问它,您都会看到这些修改。
这不会发生在数字上,因为您不能自己修改数字。您可以更改存储在数组中的哪个数字,但是不能更改数字1
来表示2
到以前使用过1
的任何地方-那就是等同于这里发生的事情。
要解决此问题,您通常只想在for循环内(而不是在循环外)创建var
数组。但是在这种情况下,由于您要迭代地将内容添加到var
并希望保存该中间状态,因此可以使用copy
:
julia> for i in 1:5
global var
global res
push!(var,i)
print(string(var,"\n"))
push!(res,copy(var))
end
Any[1]
Any[1, 2]
Any[1, 2, 3]
Any[1, 2, 3, 4]
Any[1, 2, 3, 4, 5]
julia> res
5-element Array{Any,1}:
Any[1]
Any[1, 2]
Any[1, 2, 3]
Any[1, 2, 3, 4]
Any[1, 2, 3, 4, 5]