2011-03-21 45 views
3
ruby-1.9.2-p180 :154 > a = [] 
=> [] 
ruby-1.9.2-p180 :154 > h = {:test => "test"} 
=> {:test=>"test"} 
ruby-1.9.2-p180 :155 > a << h 
=> [{:test=>"test"}] 
ruby-1.9.2-p180 :156 > h.clear 
=> {} 
ruby-1.9.2-p180 :157 > a 
=> [{}] 

我非常困惑,特别是因为我可以在不影响数组的情况下更改散列元素。但是,当我清除哈希数组更新并清除其哈希内容。有人可以解释吗?为什么要清除我的哈希,也清除哈希数组?

+0

什么是'a'?你必须在这里丢失你可能在你的irb中输入的东西。 – sawa 2011-03-21 01:18:41

回答

5

当你做a << h,你真的把h的引用传递给a。所以当你更新h时,a也会看到那些更改,因为它包含引用而不是该值的副本。

为了不在a中更改,您必须将克隆值h传递给a。

一个例子是:

a << h.clone 
+0

对不起,我应该清楚我的问题。我想知道为什么会发生这种情况,还想知道是否有一种方法可以在不影响数组的情况下使用清除方法,还是必须手动清空散列? – 2011-03-21 00:42:42

+0

完美,谢谢。 – 2011-03-21 00:45:21

+0

正如我的答案中所见,您可以克隆h(也可以在h中对数据进行新的引用),这样您就可以清除哈希而不影响数组。 – 2011-03-21 00:45:46

1

Ruby没有让这个哈希的副本当你把它添加到阵列 - 它只是存储参考给原来的变量。所以,当你清空原始变量时,存储在数组中的引用现在引用空的散列。

如果你想复制散列元素,所以这不会发生,使用Ruby的clone方法。

ruby-1.9.2-p136 :049 > h = { :test => 'foo' } 
=> {:test=>"foo"} 
ruby-1.9.2-p136 :050 > a = [] 
=> [] 
ruby-1.9.2-p136 :051 > a << h.clone 
=> [{:test=>"foo"}] 
ruby-1.9.2-p136 :052 > h.clear 
=> {} 
ruby-1.9.2-p136 :053 > a 
=> [{:test=>"foo"}]