为什么Ruby Koans练习的about_hashes.rb中的test_default_value_is_the_same_object具有数组的答案?

时间:2016-03-06 22:47:07

标签: arrays ruby hash key key-value

我正在进行ruby koans练习,并且对于test_default_value_is_the_same_object方法练习中的答案原因有点困惑。以下是代码:

def test_default_value_is_the_same_object
hash = Hash.new([])

hash[:one] << "uno"
hash[:two] << "dos"

assert_equal ["uno", "dos"], hash[:one]
assert_equal ["uno", "dos"], hash[:two]
assert_equal ["uno", "dos"], hash[:three]
end

我不确定为什么无论键是什么,值总是“uno”和“dos”?我认为当密钥为one时,返回的值应为“uno”;当key为“two”时,返回的值应为“dos”。为什么不管键是什么,值总是一个数组?

谢谢,我期待着你的回答!

2 个答案:

答案 0 :(得分:12)

hash = Hash.new([])

将使用[]实例化一个新数组(让我们称之为Harvey),然后使用Harvey作为默认值进行哈希。

hash[:one]

不存在,所以你得到哈维。 Harvey使用"uno"运算符(相当于Array#<<)将harvey.push("one")添加到他身上

hash[:two]

也不存在,所以你再次得到哈维(谁记得,已经包含"uno")。他现在也得到"dos"

hash[:three]

返回哈维,仍然使用他的"uno""dos"

如果您希望代码的行为与您认为的那样,每个密钥中使用不同的数组,则每次需要默认时都需要返回一个新数组,而不是每次都使用Harvey:

hash = Hash.new { |h, k| h[k] = [] }

如果您只想让哈希与数组无关,请忽略Harvey,并使用Hash#[]=代替Array#<<

hash = Hash.new()

hash[:one] = "uno"
hash[:two] = "dos"

答案 1 :(得分:0)

我也有同样的问题,但发现了这个答案,但并没有真正解释为什么这会使刚刚学习它的人感到困惑。仔细观察后,我发现了它为什么会如此运作。

def test_default_value_is_the_same_object
  hash = Hash.new([])

  hash[:one] << "uno"
  hash[:two] << "dos"

  assert_equal ["uno", "dos"], hash[:one]
  assert_equal ["uno", "dos"], hash[:two]
  assert_equal ["uno", "dos"], hash[:three]

  assert_equal true, hash[:one].object_id == hash[:two].object_id
end

查看分配行:

  hash[:one] << "uno"
  hash[:two] << "dos"

每个赋值都是对不存在的键的引用,该键指向默认键,然后使用append操作符(<<)将元素添加到默认键的数组中。因此,对默认键数组的所有调用现在都是[“ uno”,“ dos”]。

这也是为什么断言将两个调用(hash [:one]和hash [:two])的ID均等地比较是正确的;它们都引用默认密钥。