# 1
julia> x = [1,2,3];
julia> y = x;
julia> x = [4,5,6]
3-element Vector{Int64}:
4
5
6
julia> y
3-element Vector{Int64}:
1
2
3
#2
julia> x = [1,2,3];
julia> y = x;
julia> x[1] = 4; x[2] = 5; x[3] = 6;
julia> x
3-element Vector{Int64}:
4
5
6
julia> y
3-element Vector{Int64}:
4
5
6
我进行以上两种操作,得到的y并不同。有人能给指点下吗?
得到的y并不同
核心确实是“绑定和赋值的区别”
可以这样理解:
对于像 [1, 2, 3]
这样的数组(Array
是 mutable
的),我们假设创建时存在一个名叫"hidden1"的容器里
x = [1, 2, 3]
操作,可以看成x是一个到"hidden1"的链接
y = x
操作创建到 x 的链接,等同于到"hidden1"的链接
x = [4, 5, 6]
操作将 x 链接到新的"hidden2",而不改变 y 到"hidden1"的链接
x[1] = 4
修改"hidden1"的数据
P.S. 相关更多内容
EDIT: svg 做好了,它们稍后会被放入文档中
1 个赞
x=[1,2,3]
在堆上分配数组 [1,2,3]
, 然后初始化一个指针x
, 指向该数组。
y=x
另一个指针 y
指向 x
所指向的数组,也就是说, y
也指向 [1,2,3]
.
x=[4,5,6]
在堆上分配另一个数组 [4,5,6]
, 然后 x
指向它(x
不再指向 [1,2,3]
) ,由于 y
仍然指向 [1,2,3]
因而 [1,2,3]
没有被 gc 回收。
x=[1,2,3]
在堆上分配数组 [1,2,3]
, 然后初始化一个指针x
, 指向该数组。
y=x
另一个指针 y
指向 x
所指向的数组,也就是说, y
也指向 [1,2,3]
.
x[1] = 4; x[2] = 5; x[3] = 6;
修改了 x
指向的数组的元素,注意到 y
仍然指向这一个数组,所以你会看到 y
也被修改了。
但是实际上, x
与 y
都没变,变的是他们指向的数组,数组还是那个数组,但是数组的内容被改变了。
我也是很疑惑这种变量绑定和赋值,写程序的时候,还要注意这一点的,不然结果可能会出现问题!
这个有什么避免的方法吗?
当然有避免的方法,一种是处处使用 deepcopy
, 每次都拷贝一个新的,这样子就不用去区分了。
但是速度会变慢。另一种就是搞清楚怎么回事,以后你写代码的时候自己清楚就行了
我看到有人用for循环逐一对数组B元素赋值,而不是通过数组绑定(B=A)来避免上述问题。
这个问题应该很多人踩过坑。