为什么Ruby Koans习题的about_hashes.rb中的test_default_value_is_the_same_object是数组的答案?
Why does the test_default_value_is_the_same_object in about_hashes.rb of Ruby Koans exercises have the answer of an array?
我正在做 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"?我想当key是one
时,返回值应该是"uno";当key为"two"时,返回值应为"dos"。为什么无论键是什么,值总是一个数组?
谢谢,期待您的答复!
hash = Hash.new([])
将使用 []
实例化一个新数组(我们称它为 Harvey),然后使用 Harvey 作为其默认值进行散列。
hash[:one]
不存在,所以你找到了哈维。 Harvey 使用 Array#<<
运算符(相当于 harvey.push("one")
)
添加到他身上 "uno"
hash[:two]
也不存在,所以你又得到了 Harvey(记住,他已经包含 "uno"
)。他现在也得到 "dos"
.
hash[:three]
returns Harvey,仍然带着他的 "uno"
和 "dos"
。
如果您希望代码表现得像您认为的那样,每个键中都有不同的数组,则每次需要默认值时都需要 return 一个新数组,而不是每次都使用 Harvey:
hash = Hash.new { |h, k| h[k] = [] }
如果你只是想让散列与数组无关,请忽略 Harvey,并使用 Hash#[]=
而不是 Array#<<
:
hash = Hash.new()
hash[:one] = "uno"
hash[:two] = "dos"
我遇到了同样的问题并找到了这个答案,但它并没有真正解释为什么这会让刚刚学习它的人感到困惑。仔细观察后,我发现了它的行为方式的原因。
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"
每个赋值都是对一个不存在的键的引用,该键指向默认键,然后使用追加运算符 (<<) 将一个元素添加到默认键的数组中。因此,对默认键数组的所有调用现在都是 ["uno"、"dos"].
这也是为什么将两个调用(hash[:one] 和 hash[:two])的 id 比较为相等的断言为真;他们都引用了默认密钥。
我正在做 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"?我想当key是one
时,返回值应该是"uno";当key为"two"时,返回值应为"dos"。为什么无论键是什么,值总是一个数组?
谢谢,期待您的答复!
hash = Hash.new([])
将使用 []
实例化一个新数组(我们称它为 Harvey),然后使用 Harvey 作为其默认值进行散列。
hash[:one]
不存在,所以你找到了哈维。 Harvey 使用 Array#<<
运算符(相当于 harvey.push("one")
)
"uno"
hash[:two]
也不存在,所以你又得到了 Harvey(记住,他已经包含 "uno"
)。他现在也得到 "dos"
.
hash[:three]
returns Harvey,仍然带着他的 "uno"
和 "dos"
。
如果您希望代码表现得像您认为的那样,每个键中都有不同的数组,则每次需要默认值时都需要 return 一个新数组,而不是每次都使用 Harvey:
hash = Hash.new { |h, k| h[k] = [] }
如果你只是想让散列与数组无关,请忽略 Harvey,并使用 Hash#[]=
而不是 Array#<<
:
hash = Hash.new()
hash[:one] = "uno"
hash[:two] = "dos"
我遇到了同样的问题并找到了这个答案,但它并没有真正解释为什么这会让刚刚学习它的人感到困惑。仔细观察后,我发现了它的行为方式的原因。
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"
每个赋值都是对一个不存在的键的引用,该键指向默认键,然后使用追加运算符 (<<) 将一个元素添加到默认键的数组中。因此,对默认键数组的所有调用现在都是 ["uno"、"dos"].
这也是为什么将两个调用(hash[:one] 和 hash[:two])的 id 比较为相等的断言为真;他们都引用了默认密钥。