关于数组赋值的困惑?如何理解变量绑定和赋值的区别?

# 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] 这样的数组(Arraymutable 的),我们假设创建时存在一个名叫"hidden1"的容器里
x = [1, 2, 3] 操作,可以看成x是一个到"hidden1"的链接
varref-1

y = x 操作创建到 x 的链接,等同于到"hidden1"的链接
varref-2

x = [4, 5, 6] 操作将 x 链接到新的"hidden2",而不改变 y 到"hidden1"的链接
varref-3

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 也被修改了。
但是实际上, xy 都没变,变的是他们指向的数组,数组还是那个数组,但是数组的内容被改变了。

我也是很疑惑这种变量绑定和赋值,写程序的时候,还要注意这一点的,不然结果可能会出现问题!

这个有什么避免的方法吗?

当然有避免的方法,一种是处处使用 deepcopy, 每次都拷贝一个新的,这样子就不用去区分了。
但是速度会变慢。另一种就是搞清楚怎么回事,以后你写代码的时候自己清楚就行了

我看到有人用for循环逐一对数组B元素赋值,而不是通过数组绑定(B=A)来避免上述问题。
这个问题应该很多人踩过坑。