我对上一个问题Creating copies in Julia with = operator的答案感到困惑: 具体来说,我对StefanKarpinki在10月7日对该问题的回答下的评论感到困惑,特别是当RedPointyJackson说时
“好吧,我对此一无所知。但是当我执行b = a时,应该对其进行赋值,因为它是x = ...风格的运算,对吗?所以现在我将b“指向”了a,并且所有每当我评估b时,a的变化都应该反映出来,不是吗?” – RedPointyJackson 2015年10月9日,12:49
然后StefanKarpinski说
”是的,这是正确的,并且所有这种行为都完全符合该行为。如果执行a = b,则对b的任何更改也会影响a。如果绑定到b的值是不可变的值(例如42),则可以无论如何都不会对其进行突变,因此无法判断它是否已被复制或引用。” – StefanKarpinski,2015年10月10日,下午4:47
这些以前的注释为什么暗示着Julia命令
a = 1;
b = a;
a = 2;
将b的值更改为2? RedPointyJackson从那个线程开始,证明b将保持等于1!那么,为什么引用的注释表明b的值将变为2!?
答案 0 :(得分:3)
那么为什么引用的注释暗示b的值将变为2!?
您似乎误解了这些评论。
如果您进行
a = b
,则对b
的任何更改也会影响a
。
确切地说,应改写为“绑定到b
的值的任何更改也会影响a
。”请注意,这里唯一重要的是< em>要绑定的值 ,而不是变量名b
。因此,
a = 1; # the variable name `a` is binding to the value `1`
b = a; # the variable name `b` is binding to the value(`1`) bound to `a`
a = 2; # the variable name `a` is binding to the value `2` (`b` is still binding to `1`.)
由于1
是一个不可变的值,并且无法对其进行突变,因此,如果我们想更改“其内容”,则必须重新绑定a
/ b
。这是另一个示例:
A = [1]; # the variable name `A` is binding to the value `[1]`(an array)
B = A; # the variable name `B` is binding to the value(`[1]`) bound to `A`
A[1] = 2; # this is called mutation. the value(`[1]`) bound to `A` has been changed to `[2]`. this value is also bound to `B`, so the "content" of `B` is changed accordingly.
A = 1; # the variable name `A` is binding to the value `1` (`B` is still binding to `[2]`.)
答案 1 :(得分:1)
我正尝试用以下术语(从即将出版的书中)解释这个问题:
内存和复制问题
为了避免复制大量数据,Julia默认情况下仅复制对象的内存地址,除非程序员明确请求所谓的“深层”副本或编译器“判断”实际副本更有效。
当您不希望对复制对象的后续修改会应用于原始对象时,请使用copy()
或deepcopy()
。
详细信息:
等号(a = b)
b
引用的实体(对象)也绑定(分配)到a
标识符(变量名)b
然后重新绑定到其他对象,则a
仍然引用原始对象b
引用的对象发生突变(即内部发生变化),a
引用的对象也会发生变化(属于同一对象)b
是不可变的,并且内存很小,则在某些情况下,编译器会创建一个新对象并将其绑定到a
,但是对于用户而言,这是不可变的,因此这种区别将不明显a =复制(b)
a
。但是,该新对象可以依次通过其内存地址引用其他对象。在这种情况下,复制的是它们的内存地址,而不是引用的对象本身。a
引用的新对象将保持对原始对象的引用a
引用的新对象引用的对象也会发生变化(属于相同的对象)a =深度复制(b)