我使用默认值为空数组创建一个新哈希。
h = Hash.new([])
我将值推入密钥为'a'
的哈希值。
h['a'].push(1243)
h
为空。
h # => {}
h['a']
返回预期值。
h['a'] # => [1243]
h.keys
返回一个空数组。
h.keys # => []
如果我使用Hash.new {|h,k| h[k]=[]}
初始化第一步中的哈希值,则返回预期值。
答案 0 :(得分:4)
请注意,与块不同,所有参数仅在方法调用之前计算一次。
h
。请注意,由于您尚未使用块设置默认值,因此调用键值对不会将其分配给哈希值。'a'
不是哈希的键。您正在修改此数组实例。h
,因此调用的键值对未分配给哈希值。将您的代码与此进行比较:
h = Hash.new{|h, k| h[k] = []}
每次调用先前未调用的密钥时都会生成一个新数组,并将该键值对分配给散列。
答案 1 :(得分:1)
看起来<<
运算符会附加到默认数组本身,而不是处理它的副本。
[65] pry(main)> hash = Hash.new([])
=> {}
[66] pry(main)> hash["a"] << 0
=> [0]
[67] pry(main)> hash
=> {}
[68] pry(main)> hash["b"]
=> [0]
[69] pry(main)> hash["c"]
=> [0]
编辑:它不仅仅是<<
运算符,Array#push
也会推送到默认数组。
答案 2 :(得分:1)
让我们从不同的角度来看待这个问题。你在数组上调用push
。为什么在数组上调用push
会修改哈希?数组和散列之间没有关系。
你期望在这里发生什么:
a = []
h = Hash.new(a)
a.push(1234)
您希望h
改变吗?可能不是。但这是与你的代码完全相同的事情!
答案 3 :(得分:-1)
原因是,当您编写h = Hash.new([])
时,您创建了新的哈希值array
作为不存在的密钥的默认值,当您编写h['a'].push(1243)
时 - 您只需添加一个这个数组的新元素,当你尝试做一些像:
h['b'], h['c'], h['lol']
=> [1243]
要创建新的hash
,您只需:
第一个例子:
h = {}
h['a'] = 1243
第二个例子
h = Hash.new
h['a'] = 1243