当哈希值不存在时,为什么不抛出异常?

时间:2015-05-29 11:41:25

标签: ruby

我正在学习Ruby语言,在编写简单的打印操作时,我看到了一件奇怪的事情。代码如下:

z = { 'mike' => 75, 'bill' => 18, 'alice' => 32 }

print z['bill'], " ", z['joe'], "  "\n"

这里我得到的输出为18;即使joe没有可用值,也不会产生任何错误。

为什么会这样?在c#之类的其他语言中,它会抛出异常!

是因为我正在使用在线编译器进行编译吗?

2 个答案:

答案 0 :(得分:8)

如果在Hash中找不到哈希键,默认情况下,方法[]将返回nil。因此,在z['joe']的情况下,它将生成nil,在打印时会生成空字符串。

另一方面,初始化哈希时,您可以定义一个代码块,当哈希中不存在该键时将运行该代码块。例如:

z = Hash.new do |hash, key|
  raise("Key #{ key } is not valid")
end

作为替代方案,您也可以使用Hash#fetch并使其与KeyError一起失败,或指定要执行的默认值或代码块(如new中所示)钥匙不会退出。

答案 1 :(得分:4)

方法Hash#[]的文档中清楚地记录了这一点:

  

hsh[key]value

     

元素参考 - 检索对象对应的对象。如果未找到,则返回默认值(有关详细信息,请参阅Hash::new。)

h = { "a" => 100, "b" => 200 }
h["a"]   #=> 100
h["c"]   #=> nil

代码示例中的最后一行甚至会显示完全情况。

那么,为什么不raise Exception?好吧,因为访问字典中不存在的密钥根本不是特殊情况!

另外,使用Hash default_proc raise初始化KeyError是微不足道的:

z = { 'mike' => 75, 'bill' => 18, 'alice' => 32 }
z.default_proc = -> (h, k) { raise KeyError, "#{k} not found!" }

z['joe']
# KeyError: joe not found!

现在,如果不是指定默认值的方式,而是总是会得到异常,那么反过来实现它会更加困难。