使用=运算符在Julia中创建副本 [英] Creating copies in Julia with = operator
问题描述
当我创建一些数组A并将其分配给B
When I create some array A and assign it to B
A = [1:10]
B = A
我可以修改A,并且更改会反映在B中
I can modify A and the change reflects in B
A[1] = 42
# B[1] is now 42
但是,如果我使用标量变量执行此操作,则更改不会传播:
But if I do that with scalar variables, the change doesn't propagate:
a = 1
b = a
a = 2
# b remains being 1
我什至可以将所有东西混合在一起,然后将向量转换为标量,并且这种变化不会传播:
I can even mix the things up and transform the vector to a scalar, and the change doesn't propagate:
A = [1:10]
B = A
A = 0
# B remains being 1,2,...,10
=
运算符的确切作用是什么?当我想复制变量并修改旧变量以保留新变量的完整性时,何时应该仅在b=a
上使用b = copy(a)
?
What exactly does the =
operator does? When I want to copy variables and modify the old ones preserving the integrity of the new variables, when should I use b = copy(a)
over just b=a
?
推荐答案
混淆源于此: 赋值和变异不是同一件事.
The confusion stems from this: assignment and mutation are not the same thing.
分配.分配看起来像x = ...
– =
的左边是一个标识符,即变量名.赋值更改变量x
引用的对象(这称为变量绑定).它根本不会变异任何对象.
Assignment. Assignment looks like x = ...
– what's left of the =
is an identifier, i.e. a variable name. Assignment changes which object the variable x
refers to (this is called a variable binding). It does not mutate any objects at all.
突变.在Julia中,有两种典型的突变方法:
x.f = ...
– =
的左边是一个字段访问表达式;
x[i] = ...
– =
剩下的是一个索引表达式.当前,字段突变是基本的–语法只能 表示您正在通过更改结构的字段来对其进行突变.这可能会改变.数组突变语法不是基本的语法-x[i] = y
表示setindex!(x, y, i)
,您可以将方法添加到setindex!或本地更改哪个通用函数setindex!
.实际的数组分配是一个内置函数-用C实现的功能(并且我们知道如何生成相应的LLVM代码).
Mutation. There are two typical ways to mutate something in Julia:
x.f = ...
– what's left of the =
is a field access expression;
x[i] = ...
– what's left of the =
is an indexing expression. Currently, field mutation is fundamental – that syntax can only mean that you are mutating a structure by changing its field. This may change. Array mutation syntax is not fundamental – x[i] = y
means setindex!(x, y, i)
and you can either add methods to setindex! or locally change which generic function setindex!
. Actual array assignment is a builtin – a function implemented in C (and for which we know how to generate corresponding LLVM code).
静音会更改对象的值;它不会更改任何变量绑定.完成上述任一操作后,变量x
仍引用之前执行过的操作;但是,该对象可能具有不同的内容.特别是,如果可以从其他范围访问该对象(例如,调用一个对象进行突变的函数),则更改后的值将在此可见.但是绑定没有改变-所有作用域中的所有绑定仍然引用相同的对象.
Mutation changes the values of objects; it doesn't change any variable bindings. After doing either of the above, the variable x
still refers to the same object it did before; that object may have different contents, however. In particular, if that object is accessible from some other scope – say the function that called one doing the mutation – then the changed value will be visible there. But no bindings have changed – all bindings in all scopes still refer to the same objects.
您会注意到,在这种解释中,我从未谈论过可变性或不变性.那是因为它与这一切无关–可变和不可变的对象在赋值,参数传递等方面具有完全相同的语义.唯一的区别是,如果您尝试在x是不可变的情况下执行x.f = ...
,你会得到一个错误.
You'll note that in this explanation I never once talked about mutability or immutability. That's because it has nothing to do with any of this – mutable and immutable objects have exactly the same semantics when it comes to assignment, argument passing, etc. The only difference is that if you try to do x.f = ...
when x is immutable, you will get an error.
这篇关于使用=运算符在Julia中创建副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!