Pointers Julia中的变量副本和副本

Pointers Julia中的变量副本和副本,pointers,variables,julia,Pointers,Variables,Julia,我对前一个问题的答案感到困惑: 具体地说,我对斯特凡卡尔平基10月7日回答这个问题时的评论感到困惑,尤其是当RedPointyJackson说 “好吧,我不理解。但当我做b=a时,它应该是赋值,因为它是x=…风格的运算,对吗?所以现在我把b‘指向’a,a中的所有变化应该反映在我计算b时,不是吗?”——RedPointyJackson 10月9日15日12:49 然后StefanKarpinski说 “是的,这是正确的,所有这些行为都与此完全一致。如果你做a=b,那么对b的任何更改也会影响a。如果

我对前一个问题的答案感到困惑: 具体地说,我对斯特凡卡尔平基10月7日回答这个问题时的评论感到困惑,尤其是当RedPointyJackson说

“好吧,我不理解。但当我做b=a时,它应该是赋值,因为它是x=…风格的运算,对吗?所以现在我把b‘指向’a,a中的所有变化应该反映在我计算b时,不是吗?”——RedPointyJackson 10月9日15日12:49

然后StefanKarpinski说

“是的,这是正确的,所有这些行为都与此完全一致。如果你做a=b,那么对b的任何更改也会影响a。如果绑定到b的值是一个不可变的值,比如42,那么你无论如何都不能对它进行变异,因此无法判断它是否被复制或引用。”–StefanKarpinski 10月10日15日4:47

为什么之前的评论认为Julia命令

a = 1; 
b = a; 
a = 2; 
是否将b的值更改为2?RedPointyJackson用b将保持等于1的证据开始了这个线程!!那么,为什么引用的评论建议b的值将变为2

那么,为什么引用的评论建议b的值将变为2

看起来你误解了那些评论

如果执行
a=b
,则
b
的任何更改也会影响
a

准确地说,这应该被重新表述为“绑定到
b
的值的任何更改也会影响
a
”注意这里唯一重要的是要绑定的值,而不是变量名
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]`.)
那么,为什么引用的评论建议b的值将变为2

看起来你误解了那些评论

如果执行
a=b
,则
b
的任何更改也会影响
a

准确地说,这应该被重新表述为“绑定到
b
的值的任何更改也会影响
a
”注意这里唯一重要的是要绑定的值,而不是变量名
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]`.)

我试图用以下术语解释这个问题(来自一本即将出版的书):

内存和复制问题

为了避免复制大量数据,Julia默认情况下只复制对象的内存地址,除非程序员明确请求所谓的“深度”副本或编译器“判断”实际副本更有效

如果不希望复制对象的后续修改应用于原始对象,请使用
copy()
deepcopy()

详情如下:

等号(a=b)

  • 执行名称绑定,即将
    b
    引用的实体(对象)也绑定(分配)到
    a
    标识符(变量名称)
  • 结果是:
    • 如果
      b
      然后重新绑定到某个其他对象,
      a
      将保留对原始对象的引用
    • 如果
      b
      引用的对象发生变异(即它内部发生变化),则
      a
      引用的对象(作为同一对象)也会发生变异
  • 如果
    b
    是不可变的,并且内存很小,在某些情况下,编译器会创建一个新对象并将其绑定到
    a
    ,但是对于用户来说是不可变的,这种差异不会明显
a=副本(b)

  • 创建对象的新“独立”副本并将其绑定到
    a
    。然而,这个新对象可以通过其内存地址依次引用其他对象。在这种情况下,复制的是它们的内存地址,而不是被引用对象本身
  • 结果是:
    • 如果这些被引用的对象(例如向量的各个元素)反弹到其他对象,则
      a
      引用的新对象将保持对原始对象的引用
    • 如果这些被引用的对象发生变异,那么(相同的对象)被
      a
      a引用的新对象所引用的对象也会发生变异
a=深度复制(b)

  • 一切都是递归地深度复制的

我试图用以下术语解释这个问题(来自即将出版的一本书):

内存和复制问题

为了避免复制大量数据,Julia默认情况下只复制对象的内存地址,除非程序员明确请求所谓的“深度”副本或编译器“判断”实际副本更有效

如果不希望复制对象的后续修改应用于原始对象,请使用
copy()
deepcopy()

详情如下:

等号(a=b)

  • 执行名称绑定,即将
    b
    引用的实体(对象)也绑定(分配)到
    a
    标识符(变量名称)
  • 结果是:
    • 如果
      b
      然后重新绑定到某个其他对象,
      a
      将保留对原始对象的引用
    • 如果
      b
      引用的对象发生变异(即它内部发生变化),则
      a
      引用的对象(作为同一对象)也会发生变异
  • 如果
    b
    是不可变的,并且内存很小,在某些情况下,编译器会创建一个新对象并将其绑定到
    a
    ,但是对于用户来说是不可变的,这种差异不会被注意到