Ruby:“ m = Hash.new {| h,k | h [k] = []}”完成“ Hash.new”不是吗?

问题描述 投票:5回答:2

[在学习this Railscast的过程中,我遇到了来自Rack的以下源代码:

def self.middleware
  @middleware ||= begin
    m = Hash.new {|h,k| h[k] = []}
    m["deployment"].concat [
      [Rack::ContentLength],
      [Rack::Chunked],
      logging_middleware
    ]
    m["development"].concat m["deployment"] + [[Rack::ShowExceptions], [Rack::Lint]]
    m
  end
end

我的问题是关于第三行。将块{|h,k| h[k] = []}传递到Hash.new有什么作用?我在IRB中尝试过,它似乎与常规Hash.new没什么不同:

2.0.0p247 :003 > m1 = Hash.new
 => {} 
2.0.0p247 :004 > m2 = Hash.new{|h,k| h[k] = []}
 => {} 
2.0.0p247 :005 > m1 == m2
 => true

...但是我猜想写Rack的人比我更了解Ruby。包含该块的背后是什么原因?

ruby hash rack
2个回答
11
投票

它允许您将默认值定义为数组

h = Hash.new { |h, k| h[k] = [] }
h[:a]        # => {:a=>[]}
h[:b] << 123 # => {:a=>[], :b=>[123]}

更多示例在这里:Hash.new


0
投票

这将创建默认对象(在这种情况下为[])作为每个键的值。它隐式调用h1 [:a] = [],导致哈希中添加了密钥。

h1 = Hash.new {|h,k| h[k] = []} 
h1[:a] # = []
h1[:a].push(1) # = [1]
h1[:b] # = []
h1 #= {:a=>[1], :b=>[]}

这将返回一个默认对象作为所有键的值。

h1 = Hash.new([])
h1[:a] # = []
h1[:a].push(1) # = [1]
h1[:b] # = [1]
h1 #= {}

这将返回默认对象作为所有键的值。但不会将密钥添加到哈希中。

h1 = Hash.new{[]}
h1[:a] # = []
h1[:a].push(1) # = [1]
h1[:b] # = []
h1 #= {}
© www.soinside.com 2019 - 2024. All rights reserved.