В Ruby, когда я устанавливаю array X равным array Y и превращаю chages в array X, почему это также делается в array Y?

#arrays #ruby

#массивы #ruby

Вопрос:

В этом коде:

 letters = %w{a b c d e f g}
letters_2 = letters

i = 0
while i < letters.length
    letters[i] = "X"
    puts "letters = "   letters.join
    puts "letters_2 = "   letters_2.join
    puts "======================"

    i =1
end
  

почему массив letters_2 изменяется, когда код только явно изменяет массив букв?

Комментарии:

1. Другой способ думать об этом заключается в том, что letters и letters_2 разные имена для одного и того же объекта.

Ответ №1:

В вашем примере существует только один массив, letters и letters_2 оба они назначены ему.

Похоже, что вы хотите, чтобы это letters_2 был отдельный массив, который инициализируется из letters массива, но после этого независим? Если это так, то один из способов сделать это — использовать Array.new метод:

 letters = %w{a b c d e f g}
letters_2 = Array.new(letters)
# letters and letters_2 are now separate arrays with the same elements

letters[3] = "X" # this only affects letters, not letters_2
letters_2[4] = "Y" # this only affects letters_2, not letters
  

Комментарии:

1. @sagarpandya82: Действительно. Я перефразирую свой ответ, чтобы не подразумевать, что есть только один способ сделать это.

Ответ №2:

вы назначаете там ту же ссылку.

Вы можете увидеть здесь

 letters = %w{a b c d e f g}
letters_2 = letters

puts letters.object_id    #4579428
puts letters_2.object_id  #4579428
  

Итак, если вы хотите создать второй как отдельный массив, затем вызовите функцию ‘dup’, когда вы назначаете первый массив второму,

 letters = %w{a b c d e f g}
letters_2 = letters.dup
puts letters.object_id      #18932832
puts letters_2.object_id    #18932580
  

Комментарии:

1. Поскольку вы показали, что исходные массивы используются одинаково object_ id , возможно, вы могли бы включить object _id s последних массивов, чтобы показать, что они действительно разные.

2. @sagarpandya82 Хорошо, обновлено.

Ответ №3:

вы определяете только один массив letters

чем вы назначили letters letters_2 .итак, вы создаете тот же массив letters_2 , letters что и . поэтому любое изменение, внесенное в letters , повлияет на letters_2 .

оба массива судят одинаково object_id

вы можете проверить, что letters.object_id это то же самое, что letters_2.object_id

оба массива ссылаются на один и тот же адрес памяти.

 2.2.3 :038 > letters = %w{a b c d e f g}
 => ["a", "b", "c", "d", "e", "f", "g"] 
2.2.3 :039 > letters_2 = letters
 => ["a", "b", "c", "d", "e", "f", "g"] 
2.2.3 :040 > letters_2
 => ["a", "b", "c", "d", "e", "f", "g"] 
2.2.3 :041 > letters
 => ["a", "b", "c", "d", "e", "f", "g"] 
  

Комментарии:

1. Это то, что описано в OP. Вопрос в том, почему изменение влияет на оба?

2. @Stefan оба массива ссылаются на один и тот же адрес памяти.

3. Вы упоминаете «только один массив» в своем первом предложении, а затем «оба массива [ов]» . Это кажется противоречивым, из вашего объяснения неясно, есть ли один массив или два.

4. @Stefan я отредактировал свой ответ. Спасибо за предложение.