我将数组sequence
保存到reset
。我从sequence
删除了每个元素,执行了一项操作,然后将sequence
重置为原来的状态。
reset = sequence
(0..sequence.length).each do |i|
puts "Sequence #{sequence}, index is #{i}. Deleting #{sequence[i]}"
sequence.delete_at(i)
puts "New sequence is #{sequence.inspect}, sorted makes #{sequence.sort}, unique makes #{sequence.uniq}"
return true if sequence.sort == sequence && sequence.uniq == sequence
puts "This is reset before the sequence = reset: #{reset.inspect}"
sequence = reset
puts "Resetting sequence. Reset is #{reset.inspect}, sequence is #{sequence.inspect}"
dummy = gets.chomp
end
然后,sequence
发生的事情也发生在reset
。这是一些输出:
Sequence [1, 1, 1, 2, 3], index is 0. Deleting 1
New sequence is [1, 1, 2, 3], sorted makes [1, 1, 2, 3], unique makes [1, 2, 3]
This is reset before the sequence = reset: [1, 1, 2, 3]
Resetting sequence. Reset is [1, 1, 2, 3], sequence is [1, 1, 2, 3]
当我只是命令它从reset
删除时,它正在捣乱sequence
。情况并非reset = sequence
在循环内部。是什么赋予了?该循环应该在oldarray.size
处中断,在其中将元素推入新数组。但令人费解的是,它也将相同的数字推送到同一个数组中,从而创建了一个无限循环。
答案 0 :(得分:3)
reset
和sequence
是相同的数组。 =
运算符不会复制数组或其他对象的内容;它创建了对同一个数组的新引用。
例如,请在irb
:
irb(main):001:0> a = [ 10, 20 ]
=> [10, 20]
irb(main):002:0> b = a
=> [10, 20]
irb(main):003:0> a
=> [10, 20]
irb(main):004:0> b
=> [10, 20]
irb(main):005:0> a.push( 30 )
=> [10, 20, 30]
irb(main):006:0> b.push( 40 )
=> [10, 20, 30, 40]
irb(main):007:0> a
=> [10, 20, 30, 40]
irb(main):008:0> b
=> [10, 20, 30, 40]
在方法调用中传递数组或任何对象时也是如此。该方法没有获得对象数据的单独副本;它接收对同一对象的引用:
irb(main):001:0> a = [ 10, 20 ]
=> [10, 20]
irb(main):002:0> def foo( x ); x.push( 30 ); end
=> :foo
irb(main):003:0> foo( a )
=> [10, 20, 30]
irb(main):004:0> a
=> [10, 20, 30]
请注意,foo
并未修改其x
参数,它还修改了传递给它的a
,因为x
和{{1}两个都是对同一个数组的引用。
如果您想制作数组的副本以使其上的操作独立于原始数据,则可以使用a
或dup
:
clone
许多语言都是这样的;赋值运算符或函数参数不会复制任何数据,只是创建对同一数据的新引用。
这是Python中的相同示例:
irb(main):001:0> a = [ 10, 20 ]
=> [10, 20]
irb(main):002:0> b = a.clone
=> [10, 20]
irb(main):003:0> a
=> [10, 20]
irb(main):004:0> b
=> [10, 20]
irb(main):005:0> a.push( 30 )
=> [10, 20, 30]
irb(main):006:0> b.push( 40 )
=> [10, 20, 40]
irb(main):007:0> a
=> [10, 20, 30]
irb(main):008:0> b
=> [10, 20, 40]
并在JavaScript中:
>>> a = [ 10, 20 ]
>>> b = a
>>> a
[10, 20]
>>> b
[10, 20]
>>> a.append( 30 )
>>> b.append( 40 )
>>> a
[10, 20, 30, 40]
>>> b
[10, 20, 30, 40]
答案 1 :(得分:0)
假设我们写
sequence = [1, 1, 1, 2, 3]
reset = sequence
#=> [1, 1, 1, 2, 3]
变量sequence
和reset
不仅保持相同的值,而且保持相同的对象:
sequence.object_id
#=> 4044000
reset.object_id
#=> 4044000
请注意,变量没有对象ID;它们的价值观 - Ruby对象 - 具有独特的ID(参见Object#object_id)。当我们写sequence.object_id
时,sequence
会返回[1, 1, 1, 2, 3]
,然后会返回[1, 1, 1, 2, 3].object_id #=> 4044000
。
如果更改了对象[1, 1, 1, 2, 3]
,则两个变量的值都将等于更改的对象。
sequence.replace [1, 4]
#=> [1, 4]
sequence.object_id
#=> 4044000
reset
#=> [1, 4]
reset.object_id
#=> 4044000
另一方面,如果我们将这些变量中的任何一个设置为等于差异对象(具有不同的对象id),则另一个变量的值不受影响。
sequence = [99, 31]
sequence.object_id
#=> 5564720
reset
#=> [1, 4]
reset.object_id
#=> 4044000