Recursion 朱莉娅:关于变量绑定、变异和可变函数的问题

Recursion 朱莉娅:关于变量绑定、变异和可变函数的问题,recursion,julia,mutable,mutation,mutual-recursion,Recursion,Julia,Mutable,Mutation,Mutual Recursion,我正在用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=

我正在用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
值的副本您可以使用
复制

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]


按照您编写的方式,您可以反复推送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
发生变异之前
复制
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]

可以找到关于值与绑定的经典读物。

非常感谢@David。这个修好了!非常感谢您的参考和解决方案!这很有魅力(在我的最终实现中使用了
deepcopy()
),我已经接受了答案。旁白:编写
return x
而不是
return(x)
,这是惯用的做法,因为
return
不是一个函数,而是一个关键字。