[] # -6ren">
gpt4 book ai didi

Ruby 方法 Array#<< 不更新散列中的数组

转载 作者:数据小太阳 更新时间:2023-10-29 06:37:24 25 4
gpt4 key购买 nike

灵感来自 How can I marshal a hash with arrays?我想知道是什么原因 Array#<<在以下代码中将无法正常工作:

h = Hash.new{Array.new}
#=> {}
h[0]
#=> []
h[0] << 'a'
#=> ["a"]
h[0]
#=> [] # why?!
h[0] += ['a']
#=> ["a"]
h[0]
#=> ["a"] # as expected

这是否与 << 的事实有关?就地更改数组,而 Array#+创建一个新实例?

最佳答案

如果您创建一个 Hash使用 Hash.new 的 block 形式,每次您尝试访问实际上不存在的元素时,都会执行该 block 。那么,让我们看看会发生什么:

h = Hash.new { [] }
h[0] << 'a'

这里首先求值的是表达式

h[0]

评估时会发生什么?好吧, block 开始运行:

[]

这不是很令人兴奋:该 block 只是创建一个空数组并返回它。它没有做任何其他事情。特别是,它不会改变 h以任何方式:h仍然是空的。

接下来,消息<<有一个参数 'a'被发送到 h[0] 的结果这是 block 的结果,它只是一个空数组:

[] << 'a'

这是做什么的?它添加元素 'a'到一个空数组,但由于该数组实际上并未分配给任何变量,因此它会立即被垃圾收集并消失。

现在,如果您评估 h[0]再次:

h[0] # => []

h 仍然 是空的,因为没有任何东西被分配给它,因此键 0仍然不存在,这意味着该 block 再次运行,这意味着它再次返回一个空数组(但请注意,它是一个全新的,不同的 现在为空数组)。

h[0] += ['a']

这里发生了什么?首先,运算符 assign 被脱糖为

h[0] = h[0] + ['a']

现在,h[0] 右侧 得到评估。它返回什么?我们已经讨论过了:h[0]不存在,因此 block 得到运行, block 返回一个空数组。同样,这是一个全新的、第三个​​空数组。这个空数组被发送消息 +使用参数 ['a'] , 这导致它返回 另一个 新数组,即数组 ['a'] .然后将该数组分配给 h[0] .

最后,此时:

h[0] # => ['a']

现在您终于实际上将一些东西放入了h[0]所以,很明显,你得到了你投入的东西。

那么,为了回答您可能遇到的问题,为什么不取出您放入的内容?您一开始没有放入任何东西!

如果你真的想分配到 block 内的哈希,你必须,好分配到 block 内的哈希:

h = Hash.new {|this_hash, nonexistent_key| this_hash[nonexistent_key] = [] }
h[0] << 'a'
h[0] # => ['a']

如果您查看所涉及对象的标识,实际上很容易看出您的代码示例中发生了什么。然后你可以看到每次调用h[0] ,你会得到一个不同的数组。

关于Ruby 方法 Array#<< 不更新散列中的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2552579/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com