当你对一个数字运行hash
时,它会在同一个 ruby 进程中始终返回相同的值吗?
似乎2.hash
总是在 irb 的单个进程中返回相同的值,但是如果您关闭并重新打开 irb,则会得到不同的值。对于流程中的每个数字,它是否始终保持一致?
我相信 ruby 至少使用某些对象的内存位置来计算哈希,数字也是如此吗?如果是这样,一个数字的两个实例是否总是具有相同的内存位置?
是的,它保证在一个 Ruby 进程中是相同的。 Hash
依靠这一事实来保证唯一的密钥。否则,当对象获得新的hash
值时,长期进程最终可能会产生重复的哈希键。
关于实现和内存位置,Ruby 不保证hash
的实现。唯一的要求是:
例如,此函数必须具有
a.eql?(b)
暗示的属性a.hash == b.hash
。
在YARV中,许多对象根本不存在于内存中(例如Fixnums),而只是由特殊的对象ID标识。 x.object_id == x * 2 + 1
任何修复。
您可以使用BasicObject#__id__
,这对于 Fixnum 将保持一致(但对于较大的数字可能会变得奇怪),例如。
2.__id__
#=> 5
a = 2
a.__id__
#=> 5
b = 2
a.__id__ == b.__id__
#=> true
不管进程是什么2.__id__
总是会返回5
请注意,对于大多数对象来说并非如此,例如
{}.__id__
#=> 23077320
{}.__id__
#=> 22453800
{}.__id__
#=> 21672516
关于BasicObject#__id__
的文档
在对给定对象的所有object_id调用时将返回相同的号码,并且没有两个活动对象将共享 id。 注意:内置类的某些对象被重用以进行优化。即时值和冻结字符串文本就是这种情况。
这就是@max正确的地方__id__ == x * 2 + 1
因此2 * 2 + 1 #=> 5
但我不确定这是否会在口译员之间发生变化。
哈希函数:
为此对象生成修复数哈希值。此函数必须具有 A.EQL的财产?(b) 表示 a.hash == b.hash。
哈希值与 eql? 一起由哈希类用于确定 如果两个对象引用相同的哈希键。任何哈希值 超过容量的 Fixnum 将在使用前被截断。
对象的哈希值在调用中可能不相同 或 Ruby 的实现。如果您需要一个稳定的标识符 您需要生成一个 Ruby 调用和实现 使用自定义方法。
来源: http://ruby-doc.org/core-2.2.1/Object.html#method-i-hash
*搜索并不难