设置默认值
默认情况下,尝试查找不存在的键的值将返回 nil
。当使用不存在的密钥访问散列时,你可以选择指定要返回的其他值(或要采取的操作)。虽然这被称为默认值,但它不必是单个值; 例如,它可以是计算值,例如密钥的长度。
哈希的默认值可以传递给它的构造函数:
h = Hash.new(0)
h[:hi] = 1
puts h[:hi] # => 1
puts h[:bye] # => 0 returns default value instead of nil
也可以在已构造的哈希上指定默认值:
my_hash = { human: 2, animal: 1 }
my_hash.default = 0
my_hash[:plant] # => 0
请务必注意,每次访问新密钥时都不会复制默认值,这可能会在默认值为引用类型时导致令人惊讶的结果:
# Use an empty array as the default value
authors = Hash.new([])
# Append a book title
authors[:homer] << 'The Odyssey'
# All new keys map to a reference to the same array:
authors[:plato] # => ['The Odyssey']
为避免此问题,Hash 构造函数接受每次访问新密钥时执行的块,并将返回的值用作默认值:
authors = Hash.new { [] }
# Note that we're using += instead of <<, see below
authors[:homer] += ['The Odyssey']
authors[:plato] # => []
authors # => {:homer=>["The Odyssey"]}
注意,上面我们必须使用+ =而不是<<因为默认值不会自动分配给哈希值; 使用<<会添加到数组中,但作者[:homer]将保持未定义:
authors[:homer] << 'The Odyssey' # ['The Odyssey']
authors[:homer] # => []
authors # => {}
为了能够在访问时分配默认值,以及计算更复杂的默认值,默认块将传递散列和密钥:
authors = Hash.new { |hash, key| hash[key] = [] }
authors[:homer] << 'The Odyssey'
authors[:plato] # => []
authors # => {:homer=>["The Odyssey"], :plato=>[]}
你还可以使用默认块来执行操作和/或返回取决于键(或其他一些数据)的值:
chars = Hash.new { |hash,key| key.length }
chars[:test] # => 4
你甚至可以创建更复杂的哈希:
page_views = Hash.new { |hash, key| hash[key] = { count: 0, url: key } }
page_views["http://example.com"][:count] += 1
page_views # => {"http://example.com"=>{:count=>1, :url=>"http://example.com"}}
要在已存在的哈希上将默认值设置为 Proc,请使用 default_proc=
:
authors = {}
authors.default_proc = proc { [] }
authors[:homer] += ['The Odyssey']
authors[:plato] # => []
authors # {:homer=>["The Odyssey"]}