Julia:关于变量绑定、变异和可变函数的问题
Julia: Question about variable binding, mutating, and mutable functions
我正在用 Julia 编写代码,它从一个函数 foo
中收集一些输出(它改变了它的输入参数),我试图将这个函数的递归计算附加到一个数组中 A
.
例如,foo!(x)
通过向其每个元素添加 1
来更改 x
的值。
function foo!(x)
x .= x .+ 1
return(x)
end
julia> x = [1, 1];
julia> foo!(x);
julia> x
2-element Array{Int64,1}:
2
2
我想创建一个数组 A
来存储固定范围内 x = f(x)
的值。然而,A
只是最终包含 f(x)
最终值的多个副本,例如,
julia> x = [1, 1];
julia> A = [x];
julia> for i=1:3
push!(A, foo!(x))
end
julia> A
4-element Array{Array{Int64,1},1}:
[4, 4]
[4, 4]
[4, 4]
[4, 4]
我正在尝试让它有效地输出类似于
的东西
julia> B
4-element Array{Array{Int64,1},1}:
[1, 1]
[2, 2]
[3, 3]
[4, 4]
我无法找到有用的资源来深入理解突变,或者突变在 Julia 中的执行顺序。在这方面的任何帮助将不胜感激!
通过仅使用 push!
,您只是创建了一个对单个数组(即 x
)的引用的数组。这就是为什么您看到相同的值重复多次的原因。
如果您想在 foo!
的调用中保留 x
值的副本,您可以使用 copy
:
julia> foo!(x) = x .+= 1
foo! (generic function with 1 method)
julia> x = [0,0];
julia> A = [copy(foo!(x)) for i in 1:4]
4-element Vector{Vector{Int64}}:
[1, 1]
[2, 2]
[3, 3]
[4, 4]
按照您编写的方式,您重复将同一对象 push!
放入 A
,您的 foo!
函数会发生变异:
julia> x = [1, 1]
2-element Vector{Int64}:
1
1
julia> A = [x]
1-element Vector{Vector{Int64}}:
[1, 1]
julia> foo!(x)
2-element Vector{Int64}:
2
2
julia> A
1-element Vector{Vector{Int64}}:
[2, 2]
解决此问题的一种方法是在 x
发生突变之前 copy
A
中的元素:
julia> for i ∈ 1:3
A[i] = copy(x)
push!(A, foo!(x))
end
julia> A
4-element Vector{Vector{Int64}}:
[1, 1]
[2, 2]
[3, 3]
[4, 4]
可以找到有关值与绑定的经典读物 here。
我正在用 Julia 编写代码,它从一个函数 foo
中收集一些输出(它改变了它的输入参数),我试图将这个函数的递归计算附加到一个数组中 A
.
例如,foo!(x)
通过向其每个元素添加 1
来更改 x
的值。
function foo!(x)
x .= x .+ 1
return(x)
end
julia> x = [1, 1];
julia> foo!(x);
julia> x
2-element Array{Int64,1}:
2
2
我想创建一个数组 A
来存储固定范围内 x = f(x)
的值。然而,A
只是最终包含 f(x)
最终值的多个副本,例如,
julia> x = [1, 1];
julia> A = [x];
julia> for i=1:3
push!(A, foo!(x))
end
julia> A
4-element Array{Array{Int64,1},1}:
[4, 4]
[4, 4]
[4, 4]
[4, 4]
我正在尝试让它有效地输出类似于
的东西julia> B
4-element Array{Array{Int64,1},1}:
[1, 1]
[2, 2]
[3, 3]
[4, 4]
我无法找到有用的资源来深入理解突变,或者突变在 Julia 中的执行顺序。在这方面的任何帮助将不胜感激!
通过仅使用 push!
,您只是创建了一个对单个数组(即 x
)的引用的数组。这就是为什么您看到相同的值重复多次的原因。
如果您想在 foo!
的调用中保留 x
值的副本,您可以使用 copy
:
julia> foo!(x) = x .+= 1
foo! (generic function with 1 method)
julia> x = [0,0];
julia> A = [copy(foo!(x)) for i in 1:4]
4-element Vector{Vector{Int64}}:
[1, 1]
[2, 2]
[3, 3]
[4, 4]
按照您编写的方式,您重复将同一对象 push!
放入 A
,您的 foo!
函数会发生变异:
julia> x = [1, 1]
2-element Vector{Int64}:
1
1
julia> A = [x]
1-element Vector{Vector{Int64}}:
[1, 1]
julia> foo!(x)
2-element Vector{Int64}:
2
2
julia> A
1-element Vector{Vector{Int64}}:
[2, 2]
解决此问题的一种方法是在 x
发生突变之前 copy
A
中的元素:
julia> for i ∈ 1:3
A[i] = copy(x)
push!(A, foo!(x))
end
julia> A
4-element Vector{Vector{Int64}}:
[1, 1]
[2, 2]
[3, 3]
[4, 4]
可以找到有关值与绑定的经典读物 here。