設定預設值

預設情況下,嘗試查詢不存在的鍵的值將返回 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"]}