【发布时间】:2016-01-02 14:34:00
【问题描述】:
如果一个哈希有不止一次的相同键指向不同的值,那么 Ruby 如何确定哪个值分配给该键?
换句话说,
hash = {keyone: 'value1', keytwo: 'value2', keyone: 'value3'}
结果
warning: duplicated key at line 1 ignored: :keyone
但我怎么知道分配给:keyone 的值是什么?
【问题讨论】:
如果一个哈希有不止一次的相同键指向不同的值,那么 Ruby 如何确定哪个值分配给该键?
换句话说,
hash = {keyone: 'value1', keytwo: 'value2', keyone: 'value3'}
结果
warning: duplicated key at line 1 ignored: :keyone
但我怎么知道分配给:keyone 的值是什么?
【问题讨论】:
最后一个会覆盖之前的值。在这种情况下,"value3" 成为:keyone 的值。这与merge 相同。当您合并两个具有相同键的散列时,后一个散列中的值(不是接收者而是参数)会覆盖另一个值。
【讨论】:
重复键警告的行号可能会产生误导。正如此处的其他答案所证实的那样,重复键的每个值都将被忽略,除了为该键定义的 last 值。
跨多行使用问题中的示例:
1 hash1 = {key1: 'value1',
2 key2: 'value2',
3 key1: 'value3'}
4 puts hash1.to_s
keydup.rb:1: warning: duplicated key at line 3 ignored: :key1
{:key1=>"value3", :key2=>"value2"}
消息说“第 3 行被忽略”,但实际上是在 第 1 行 处定义的键的值被忽略,而使用第 3 行的值,因为那是传递给该键的最后一个值。
【讨论】:
IRB 是你的朋友。在命令行中尝试以下操作:
irb
hash = {keyone: 'value1', keytwo: 'value2', keyone: 'value3'}
hash[:keyone]
你得到了什么?应该是“value3”。
检查这些事情的最佳方法就是尝试一下。这是 Ruby 的一大优点。
【讨论】:
这在 ISO Ruby 语言规范的第 11.5.5.2 节 Hash 构造函数 中有明确说明:
11.5.5.2 哈希构造函数
语义
[...]
b) 2) 对于每个关联Ai,按照它在程序文本中出现的顺序,采取以下步骤:
i) 评估 Ai 的 association-key 的 operator-expression。令 Ki 为结果值。
ii) 评估 association-value 的 operator-expression。令 Vi 为结果值。
iii) 在H中存储一对Ki和Vi > 通过使用 Ki 和 Vi在 H 上调用方法
[]=> 作为参数。
【讨论】: