我进行了以下测试:
irb(main):023:0> a=[]
=> []
irb(main):024:0> b="1"
=> "1"
irb(main):025:0> a.push(b)
=> ["1"]
irb(main):026:0> a
=> ["1"]
irb(main):027:0> b="2"
=> "2"
irb(main):028:0> a
=> ["1"]
到目前为止一切顺利。现在,但一旦我将 b 更改为散列:
irb(main):012:0> a=[]
=> []
irb(main):013:0> b={}
=> {}
irb(main):014:0> b[:file]="one"
=> "one"
irb(main):015:0> a.push(b)
=> [{:file=>"one"}]
irb(main):016:0> a
=> [{:file=>"one"}]
irb(main):017:0> b[:file]="two"
=> "two"
irb(main):018:0> a
**=> [{:file=>"two"}]**
我什至没有将 b 值压入 a 数组。这里发生了什么?
最佳答案
b
不是哈希。它是对散列的引用。将引用推送到其他地方不会使其指向新实例。
使用 b.dup
将您的散列显式复制到您想要的位置。
有时这可能还不够,因为这同样适用于散列内部的值:新散列内部将具有相同的引用,这就是所谓的“浅拷贝” .
(我在这里声称字符串在 Ruby 中是不可变的,但@BroiSatse 指出这不是真的,他是对的,请点击评论中的链接。)
无论如何,解释是相似的:将新字符串赋值到变量中会产生对字符串的新引用(不会改变现有字符串),将新值写入散列中不会产生新的散列引用(而是改变现有散列)。
关于ruby-on-rails - 数组/哈希奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26089735/