使用=运算符在Julia中创建副本

Red*_*son 17 julia

当我创建一些数组A并将其分配给B时

A = [1:10]
B = A
Run Code Online (Sandbox Code Playgroud)

我可以修改A,更改反映在B中

A[1] = 42
# B[1] is now 42
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用标量变量执行此操作,则更改不会传播:

a = 1
b = a
a = 2
# b remains being 1
Run Code Online (Sandbox Code Playgroud)

我甚至可以将事物混合起来并将矢量转换为标量,并且变化不会传播:

A = [1:10]
B = A
A = 0
# B remains being 1,2,...,10
Run Code Online (Sandbox Code Playgroud)

=运营商究竟做了什么?当我要复制的变量和修改旧的保存新变量的完整性,当我应该使用b = copy(a)经过短短b=a

Ste*_*ski 28

混乱源于此:分配变异不是一回事.

分配.分配看起来x = ...- 剩下的=是标识符,即变量名称.对象变量x引用的赋值更改(这称为变量绑定).它根本不会改变任何对象.

突变.在Julia中有两种典型的变异方法: x.f = ...- 剩下的=是一个字段访问表达式; x[i] = ...- 剩下的=是索引表达式.目前,字段变异是基本的 - 语法只能意味着您通过更改字段来改变结构.这可能会改变.数组变异语法不是基础 - x[i] = y意味着setindex!(x, y, i)您可以向setindex添加方法!或本地更改哪个通用功能setindex!.实际的数组赋值是一个内置函数 - 一个用C实现的函数(我们知道如何生成相应的LLVM代码).

变异会改变对象的值; 它不会更改任何变量绑定.执行上述任一操作后,变量x仍然引用之前执行的相同对象; 但是,该对象可能具有不同的内容.特别是,如果该对象可以从其他一些范围访问 - 比如调用一个进行变异的函数 - 则更改的值将在那里可见.但是没有绑定发生变化 - 所有范围内的所有绑定仍然引用相同的对象.

你会注意到,在这个解释中,我从未谈过可变性或不变性.这是因为它与任何这一点无关 - 可变和不可变对象在赋值,参数传递等方面具有完全相同的语义.唯一的区别是,如果你尝试x.f = ...在x是不可变的时候做,你会得到一个错误.