考虑以下代码:
h = Hash.new(0) # New hash pairs will by default have 0 as values
h[1] += 1 #=> {1=>1}
h[2] += 2 #=> {2=>2}
Run Code Online (Sandbox Code Playgroud)
这一切都很好,但是:
h = Hash.new([]) # Empty array as default value
h[1] <<= 1 #=> {1=>[1]} ? Ok
h[2] <<= 2 #=> {1=>[1,2], 2=>[1,2]} ? Why did `1` change?
h[3] << 3 #=> {1=>[1,2,3], 2=>[1,2,3]} ? Where is `3`?
Run Code Online (Sandbox Code Playgroud)
在这一点上,我希望哈希是:
{1=>[1], 2=>[2], 3=>[3]}
Run Code Online (Sandbox Code Playgroud)
但它远非如此.发生了什么,我怎样才能得到我期望的行为?
今天我尝试了以下代码片段,我不明白为什么我们之间会得到不同的结果.据我所知,他们是一样的.
一个使用默认值off Hash,另一个代码段在访问之前为密钥创建一个空数组.
任何了解发生了什么的人?:)
# Hash default if the key doesn't have a value set is an empty Array
a = Hash.new([])
a[:key] << 2 # => [2]
p a # => {} nil
p a[:key] # => [2]
p a.keys # => []
p a.values # => []
# Explicitly add an array for all nodes before creating
b = Hash.new
b[:key] ||= []
b[:key] << 2 # => [2]
p b # => {:key=>[2]}
p b.keys # …Run Code Online (Sandbox Code Playgroud)