Ruby 为什么将字符串铲入散列会导致这种结果?
我正在研究Ruby Koans,以便更好地掌握Ruby和TDD。我在Ruby 为什么将字符串铲入散列会导致这种结果?,ruby,Ruby,我正在研究Ruby Koans,以便更好地掌握Ruby和TDD。我在关于_hashes.rb的代码中找到了第93行,这让我很困惑它是如何被推到默认构造函数而不是散列值中的。出于好奇,我尝试用同样的东西和字符串作为构造函数的参数,它产生了类似的结果 现在我的问题是,无论我使用什么键,为什么都会检索到相同的对象,以及如何在方法中的哈希中的特定键处将新对象铲入数组test\u default\u value\u是相同的对象? def test_default_value_is_the_same_obj
关于_hashes.rb的代码中找到了第93行,这让我很困惑它是如何被推到默认构造函数而不是散列值中的。出于好奇,我尝试用同样的东西和字符串作为构造函数的参数,它产生了类似的结果
现在我的问题是,无论我使用什么键,为什么都会检索到相同的对象,以及如何在方法中的哈希中的特定键处将新对象铲入数组test\u default\u value\u是相同的对象
?
def test_default_value_is_the_same_object
hash = Hash.new([])
hash[:one] << "uno"
hash[:two] << "dos"
assert_equal ["uno", "dos"], hash[:one] #why not ["uno"]?
assert_equal ["uno", "dos"], hash[:two] #why not ["dos"]?
assert_equal ["uno", "dos"], hash[:three] #why not []?
assert_equal true, hash[:one].object_id == hash[:two].object_id
end
def test_default_value_with_block
hash = Hash.new {|hash, key| hash[key] = [] }
hash[:one] << "uno"
hash[:two] << "dos"
assert_equal ["uno"], hash[:one]
assert_equal ["dos"], hash[:two]
assert_equal [], hash[:three]
end
def test_default_value_是同一对象
hash=hash.new([])
hash[:one]您已经创建了一个新的hash
,当密钥不存在时,使用数组作为累加器
hash = Hash.new([])
hash[:one] << "uno"
hash[:one] == ["uno"] #=> true
要解决这个问题,可以使用第二次测试中提到的语法
hash = Hash.new {|h,k| h[k] = [] }
这意味着对于每个新键,都要实例化一个新的数组作为其值,而不是一次又一次地重复使用相同的数组
这就是当obj
是可变对象时,Hash.new(obj)
语法的问题有关原因的提示出现在测试名称中
test\u default\u value\u是\u同一个\u对象
显示,当您请求散列[:一些尚未存在的\u值]
,默认情况下,您会返回指定的默认值——每次都是同一个对象。通过修改该对象,可以为每个不存在的键修改它。修改散列[:one]
也会修改散列[:two]
test\u default\u value\u with\u block
显示了使用块构造哈希的过程,该块将用于为每个键提供新值。当您这样做时,hash[:one]
和hash[:two]
的值是不同的。“如何将新对象铲入数组hash[:one]”-嗯?就像你在上面做的那样hash[:one]@SergioTulentsev我在问为什么hash[:one]上的数组与hash上的数组相同[:two]@marmeladze:ruby koans
是一个元标记,请不要创建这样的标记,我们烧掉标记是有原因的,请注意,在执行hash[:one]@SergioTulentsev时要注意一点,谢谢,我完全忘记了钥匙,甚至没有分配任何东西。我试过了,然后打印了值,结果就像我预期的那样。答案很清楚。
a = []
hash = {}
hash.fetch(:one,a) << 'uno'
hash.fetch(:two,a) << 'dos'
hash.fetch(:three, a)
#=> ['uno','dos']
hash
#=> {}
hash = Hash.new {|h,k| h[k] = [] }