Дубликаты и копии переменных в Julia - PullRequest
1 голос
/ 28 апреля 2019

Я смущен ответами на этот предыдущий вопрос Создание копий в Julia с оператором = : В частности, меня смущают комментарии под ответом Стефана Карпинки 7 октября на этот вопрос, особенно когда RedPointyJackson сказал

"Хорошо, я понимаю это. Но когда я делаю b = a, это должно быть присваивание, потому что это операция в стиле x = ..., верно? Итак, теперь я" указал "на a,и все изменения в a должны отражаться всякий раз, когда я оцениваю b, не так ли? "- RedPointyJackson 9 октября 15 в 12: 49

, а затем Стефан Карпински сказал

"Да, это правильно, и все это поведение полностью соответствует этому. Если вы делаете a = b, толюбое изменение в b также влияет на a. Если значение, связанное с b, является неизменным значением, например, 42, то вы все равно не можете изменить его, поэтому невозможно определить, было ли оно скопировано или на него есть ссылка. "- StefanKarpinski 10 октября 15 в 4: 47

Почему в этих предыдущих комментариях предполагается, что команды Julia

a = 1; 
b = a; 
a = 2; 

изменят значение b на 2?RedPointyJackson запустил этот поток с доказательством того, что b останется равным 1 !!Итак, почему цитируемые комментарии предполагают, что значение b изменится на 2!?

Ответы [ 2 ]

3 голосов
/ 28 апреля 2019

Так почему цитируемые комментарии предполагают, что значение 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]`.)
1 голос
/ 29 апреля 2019

Я пытаюсь объяснить эту проблему в следующих терминах (из следующей книги):

Проблемы с памятью и копированием

Во избежание копирования большого количестваданных, Джулия по умолчанию копирует только адрес памяти объектов, если только программист явно не запросит так называемую «глубокую» копию или компилятор не «оценит» фактическую копию более эффективно.

Используйте copy() или deepcopy(), если вы не хотите, чтобы последующие модификации скопированного объекта применялись к исходному объекту.

Подробнее:

Знак равенства (a = b)

  • выполняет привязку имени , то есть связывает (назначает) объект (объект), на который ссылается b, такжеa идентификатор (имя переменной)
  • это приводит к тому, что:
    • если b затем привязывается к другому объекту, a остается ссылкой на исходный объект
    • если объект, на который ссылается b, видоизменяется (то есть изменяется внутри), то же самое происходит (будучи тем же объектом) с объектами, на которые ссылается a
  • , если b является неизменнымНебольшой объем памяти, при некоторых обстоятельствах компилятор вместо этого создает новый объект и связывает его с a, но, будучи неизменным для пользователя, это различие не будет заметно

a =copy (b)

  • создает новую, "независимую" копию объекта иЯ связал бы это с a.Однако этот новый объект может, в свою очередь, ссылаться на другие объекты через их адрес памяти.В этом случае копируется адрес их памяти, а не сами ссылочные объекты.
  • это приводит к тому, что:
    • , если эти ссылочные объекты (например, отдельные элементы вектора) возвращаются кВ некоторых других объектах новый объект, на который ссылается a, сохраняет ссылку на исходные объекты
    • , если эти ссылочные объекты видоизменяются, поэтому (будучи теми же объектами) те, на которые ссылается новый объект, на который ссылается a

a = глубокая копия (b)

  • все рекурсивно копируется глубоко
...