【发布时间】:2012-01-04 08:53:39
【问题描述】:
我不明白 Ruby 哈希是如何工作的。
我希望这些:
a = 'a'
{a => 1}[a] # => 1
{a: 1}[:a] # => 1
{2 => 1}[2] # => 1
这是如何工作的?
{'a' => 1}['a'] # => 1
第一个字符串'a'与第二个字符串'a'不是同一个对象。
【问题讨论】:
我不明白 Ruby 哈希是如何工作的。
我希望这些:
a = 'a'
{a => 1}[a] # => 1
{a: 1}[:a] # => 1
{2 => 1}[2] # => 1
这是如何工作的?
{'a' => 1}['a'] # => 1
第一个字符串'a'与第二个字符串'a'不是同一个对象。
【问题讨论】:
Ruby 不使用对象相等性 (equal?) 来比较哈希键。如果它确实有用,那将不是很有用。
相反,它使用eql?,对于字符串,它与== 相同
【讨论】:
作为其他答案的脚注,您可以让哈希的行为符合您的预期:
h = {'a'=> 1}
p h['a'] #=> 1
h.compare_by_identity
p h['a'] #=> nil ; not the same object
【讨论】:
some_hash[k] = v
基本上,当您执行此操作时,存储的内容不是直接关联k => v。取而代之的是,k 被要求提供 hash code,然后用于映射到 v。
相等的值产生相等的哈希码。这就是为什么您的最后一个示例会以这种方式工作的原因。
几个例子:
1.9.3p0 :001 > s = 'string'
=> "string"
1.9.3p0 :002 > 'string'.hash
=> -895223107629439507
1.9.3p0 :003 > 'string'.hash == s.hash
=> true
1.9.3p0 :004 > 2.hash
=> 2271355725836199018
1.9.3p0 :005 > nil.hash
=> 2199521878082658865
【讨论】:
Hash 使用eql?,而不是equal? 来确定相等性。