为什么Hash初始化的功能差异?

时间:2013-03-13 22:27:03

标签: ruby

是否有关于初始化差异的文档?关于哈希的文档中没有任何可以解释其差异的文档。

foo = [1,2,3,4]
test1 = Hash.new([])
test2 = Hash.new{|h,k| h[k] = []}

foo.each do |i| 
    test1[i] << i 
    test2[i] << i
end

puts "test 1: #{test1.size}" #0
puts "test 2: #{test2.size}" #4

3 个答案:

答案 0 :(得分:3)

在文档中提到了。阅读the doc

new(obj) → new_hash
new {|hash, key| block } → new_hash
  

[...]如果指定了obj,则此单个对象将用于所有默认值。如果指定了一个块,它将使用哈希对象和键调用,并应返回默认值。如果需要,该块负责将值存储在哈希值中。

h = Hash.new("Go Fish")
h["a"] = 100
h["b"] = 200
h["a"]           #=> 100
h["c"]           #=> "Go Fish"
# The following alters the single default object
h["c"].upcase!   #=> "GO FISH"
h["d"]           #=> "GO FISH"
h.keys           #=> ["a", "b"]

# While this creates a new default object each time
h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
h["c"]           #=> "Go Fish: c"
h["c"].upcase!   #=> "GO FISH: C"
h["d"]           #=> "Go Fish: d"
h.keys           #=> ["c", "d"]

答案 1 :(得分:1)

这是常见问题。使用test1(非块),您正在修改默认对象,即当哈希中不存在密钥时获得的东西。

foo = [1,2,3,4]
test1 = Hash.new([])
test2 = Hash.new{|h,k| h[k] = []}

foo.each do |i| 
    test1[i] << i 
    test2[i] << i
    p test1['doesnotexist'] #added line
end

puts "test 1: #{test1.size}" #0
puts "test 2: #{test2.size}" #4

输出:

[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
test 1: 0
test 2: 4

答案 2 :(得分:1)

有区别,在某些情况下可能很重要

test1 = Hash.new([])
test2 = Hash.new{|h,k| h[k] = []}

test1['foo'] #=> []
test2['foo'] #=> []

test1.keys == test2.keys #=> false

第一个构造只返回默认值,但不对当前哈希做任何事情,但第二个构造用键/值初始化哈希值,其中值由给定块计算。