将整数用作哈希键

在 Ruby 散列中使用整数作为键合适吗?

文档中的每个示例都显示一个字符串或符号用作键,但从不显示整数。

在内部,整数会以某种方式转换成字符串吗? 我已经看到了一些关于这个主题的相互矛盾的信息。

换句话说,对散列使用整数键有什么明显的缺点吗?

38949 次浏览

当然你可以用整数作为键..。

h = {1 => 'one', 2 => 'two', 3 => 'three'}


(1..3).each do |i|
puts h[i]
end
 

= >

one
two
there

IRB 是你的朋友! 试试看. 。


实际上,您可以使用 任何 Ruby 对象作为键(或值)。 我们通常不会考虑像这样使用 Hash,但是它可能非常有用。

编辑: 正如 Ócar López 指出的,对象只需要响应 .hash就可以作为 Ruby Hash 中的键。

使用对象作为散列键的惟一要求是,它必须使用散列值响应消息散列,并且给定键的散列值不得更改。例如,如果你称之为:

1.hash()

您可以看到数字1确实响应散列消息

关于 is it possible?已经有答案了。

一个解释,为什么没有整数作为哈希键的例子。

散列键(大多数情况下)有一个含义。它可能是一个属性名称及其值(例如 :color => 'red'...)。

当你有一个整数作为一个关键字,你的语义可能是“第一,第二...”(1)。但是您不使用散列,而是使用数组来存储您的值。

(1)反例可以是数据库中的外键。

在这里查看答案的其他人可能会发现有趣的是,当您在 Ruby Hash {symbol: value}中使用整数作为符号键时会发生异常

hash = {1: 'one'} # will not work
hash = {1 => 'one'} # will work

请求说明:

为什么第一个例子失败的最简单的答案可能是 to_sym不是一个已经为 菲克斯纳姆整数实现的方法。

为了更深入地解释为什么会这样,使用符号的一个主要好处是,两个符号实际上是“同一个对象”。或者至少它们共享相同的对象 ID。

:foo.object_id == :foo.object_id
=> true

相同的字符串不共享相同的对象,因此不共享相同的对象 id。

"foo".object_id == "foo".object_id
=> false

与符号一样,相同的 Fixnum 整数也有相同的对象 id。因此,您实际上并不需要将它们转换为符号。

one = 1
=> 1
uno = 1
=> 1
one.object_id
=> 3
one.object_id == uno.object_id
=> true