在Ruby中,为什么向具有默认空数组值的哈希表附加数组会失败?

7
以下是代码示例。调用哈希值的附加操作返回正确,但哈希本身的行为并不符合我的预期。
ruby-1.9.2-p290 :037 >   r = {}
 => {} 
ruby-1.9.2-p290 :038 > r.default = []
 => [] 
ruby-1.9.2-p290 :039 > r["c"] << 1
 => [1] 
ruby-1.9.2-p290 :040 > r["c"] 
 => [1] 
ruby-1.9.2-p290 :041 > r
 => {} 
ruby-1.9.2-p290 :042 > r.empty?
 => true 
2个回答

8

关于default=的文档说明:

设置默认值,也就是当哈希表中不存在某个键时返回的值。无法将默认值设置为在每次键查找时执行的Proc。

所以您可以使用以下方法:

irb(main):037:0> h = Hash.new { |hash, key| hash[key] = [] }
=> {}
irb(main):038:0> h[1] << "2"
=> ["2"]
irb(main):039:0> h
=> {1=>["2"]}

同时您也可以使用default_proc

irb(main):047:0> h = {}
irb(main):047:0> h.default_proc =  proc {|hash, key| hash[key] = []}
=> #<Proc:0x23939a0@(irb):47> 
irb(main):049:0> h[1] << 3
=> [3]
irb(main):050:0> h
=> {1=>[3]}

Nash,感谢您提供的解决方案! - zerocap
太棒了。我在许多地方都使用子类化哈希来进行类型转换,而整个过程中我本可以用这种方式来完成! - d11wtq
糟糕,不是这样的,误解了,是我的错。 - d11wtq

4
似乎 ruby 哈希表使用 r.default 作为任何 r[<未分配的键>] 的默认值。因此,即使指定了不同的未分配键,单个值也会更改。请参见下面的示例:
irb(main):001:0> r = {}
=> {}
irb(main):002:0> r.default = []
=> []
irb(main):003:0> r["c"] << 1
=> [1]
irb(main):004:0> r["c"]
=> [1]
irb(main):005:0> r["b"] << 2
=> [1, 2]
irb(main):006:0> r["b"]
=> [1, 2]
irb(main):007:0> r["c"]
=> [1, 2]
irb(main):010:0> r.default
=> [1, 2]
irb(main):008:0> r
=> {}
irb(main):009:0> r.empty?
=> true

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接