Ruby哈希初始化器

Jas*_* Yu 4 ruby hash autovivification

哈希初始值设定项:

# this
animals = Hash.new { [] }
animals[:dogs] << :Scooby
animals[:dogs] << :Scrappy
animals[:dogs] << :DynoMutt
animals[:squirrels] << :Rocket
animals[:squirrels] << :Secret
animals #=> {}
# is not the same as this
animals = Hash.new { |_animals, type| _animals[type] = [] }
animals[:dogs] << :Scooby
animals[:dogs] << :Scrappy
animals[:dogs] << :DynoMutt
animals[:squirrels] << :Rocket
animals[:squirrels] << :Secret
animals #=> {:squirrels=>[:Rocket, :Secret], :dogs=>[:Scooby, :Scrappy, :DynoMutt]}
Run Code Online (Sandbox Code Playgroud)

我看到有人在另一个问题上发布这些内容,但我不明白为什么动物在第一种情况下显得空白.如果我输入

animals[:dogs]
Run Code Online (Sandbox Code Playgroud)

我得到了合适的数组.

Voj*_*vic 7

第一种形式指定返回未找到的键的默认值的块.这意味着当你调用时animals[:dogs],:dogs哈希中没有键,所以你的块被调用并animals[:dogs]计算你的块的结果,即[].然后发生的是<< :Scooby附加:Scooby到那个空列表,然后很高兴丢弃.

第二种形式指定了当请求密钥并且未找到密钥时,作为参数接收散列本身和尚未找到的密钥的块.它是第一个构造函数的稍微强大的版本.不同之处在于您的块所做的事情.在第二种形式中,您修改散列以[]与尚未找到的键相关联.所以现在它存储在哈希中<< :Scooby并将存储:Scooby在那里.进一步调用:dog不会触发块,因为现在:dog存在于哈希中.