朱莉娅

时间:2019-04-27 23:43:06

标签: pointers variables julia

我对上一个问题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!?

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)

  • 所有内容都经过递归深层复制