Ruby 允许您定义散列的默认值:
h=Hash.new(['alright'])
h['meh'] # => ["alright"]
显示散列时会显示值的分配,但不会显示修改后的默认值。 '坏'
在哪里?
h['good']=['fine','dandy']
h['bad'].push('unhappy')
h # => {"good"=>["fine", "dandy"]}
如果我们明确询问,
'bad'
会出现。
h['bad'] # => ["alright", "unhappy"]
为什么修改后的默认值显示hash时不显示?
Hash 的默认值并不像您期望的那样工作。当你说 h[k]
时,过程是这样的:
- 如果我们有一个
k
键,返回它的值。
- 如果我们有哈希的默认值,则返回该默认值。
- 如果我们有一个提供默认值的 block ,执行该 block 并返回它的返回值。
请注意,(2) 和 (3) 根本没有提及将 k
插入到哈希中。默认值基本上将 h[k]
变成这样:
h.has_key?(k) ? h[k] : the_default_value
因此,简单地访问一个不存在的键并取回默认值不会将丢失的键添加到哈希中。
此外,任何形式:
Hash.new([ ... ])
# or
Hash.new({ ... })
几乎总是一个错误,因为您将为所有默认值共享完全相同的默认数组或哈希。例如,如果您这样做:
h = Hash.new(['a'])
h[:k].push('b')
然后 h[:i]
, h[:j]
, ... 都会返回 ['a', 'b']
而这很少是您想要的。
我认为您正在寻找 block form of the default value :
h = Hash.new { |h, k| h[k] = [ 'alright' ] }
这会做两件事:
- 访问一个不存在的键会将该键添加到散列中,并将提供的数组作为其值。
- 所有默认值都是不同的对象,因此更改一个不会更改其余值。