我正在尝试使用以下键存储二维哈希:
- 维度 1 = 数字但不连续
- 维度 2 = 字符串(作为 :id 和 :value)
当元素未初始化时会出现问题。
memory = Hash.new(Hash.new(""))
memory[0][:value] = "station1"
memory[1][:value] # => "station1"
当我访问memory[1][:value]
时,我得到 的值memory[0][:value]
。这怎么可能?我虽然会得到一个空字符串。
下面是发生的情况:在第一行中,您创建了一个 Hash 对象,该对象的默认值是 Hash 对象,该对象的默认值是空字符串。当您访问不存在的键时,将返回该对象:
irb(main):004:0> memory = Hash.new(Hash.new(""))
=> {}
irb(main):007:0> memory[0].object_id
=> 70350452886020
irb(main):008:0> memory[1].object_id
=> 70350452886020
irb(main):005:0> memory[0][:value]
=> ""
irb(main):006:0> memory[0][:value].object_id
=> 70137307419240
irb(main):007:0> memory[1][:value].object_id
=> 70137307419240
当您访问内部哈希的不存在值时,将返回默认哈希对象。因此,通过memory[0][:value] = "station1"
使用尚未存在的键 0 进行定义,您station1
可以将键的值设置为:value
内部散列。当您现在访问外部散列上的另一个不存在的键时,将再次返回内部散列,并且该键:value
已设置为"station1"
:
irb(main):008:0> memory[0][:value] = 'station1'
=> "station1"
irb(main):011:0> memory[0][:value]
=> "station1"
irb(main):012:0> memory[1][:value]
=> "station1"
irb(main):007:0> memory[0].object_id
=> 70350452886020
irb(main):008:0> memory[1].object_id
=> 70350452886020
irb(main):009:0> memory[0][:value].object_id
=> 70137307342120
irb(main):010:0> memory[1][:value].object_id
=> 70137307342120
所以基本上你通过访问外部散列上不存在的键来更改内部散列,这会返回对内部散列的引用。
您需要为每个键创建一个新的哈希对象。在您的示例中,所有键共享相同的哈希对象。
memory = Hash.new{|h, k| h[k] = Hash.new("")}
memory[1][:value] # => ""
memory[1][:value] = "a"
memory[1][:value] # => "a"
memory[2][:value] # => ""