这是我的代码:
a=["foo","foo","foo"]
b=["foo"]*3
a==b # => true
a.each{|i| i<<"bar"}
b.each{|i| i<<"bar"}
a==b # => false
我得到了a
的期望:
["foobar", "foobar", "foobar"]
但对于b
,我明白了:
["foobarbarbar", "foobarbarbar", "foobarbarbar"]
答案 0 :(得分:7)
这不是一个错误,只是行
a=["foo","foo","foo"]
b=["foo"]*3
不一样。第二个是将SAME OBJECT三次插入b
数组。在a
数组中,您有三个不同的对象。在所有情况下,对象都是带有文本“foo”的字符串。
您可以通过检查对象ID来确认。
a[0].object_id == a[1].object_id
=> false
b[0].object_id == b[1].object_id
=> true
因此当您使用<< "bar"
变异对象时,您将对同一对象进行三次变异(在数组b
的情况下)
要使用相同字符串的单独实例填充数组,请执行...
Array.new(3) { "foo" }
答案 1 :(得分:1)
就像SteveTurczyn所说,["foo"]*3
创建一个数组连接同一个对象("foo"
)的三倍的数组。
如果你应该使用某些函数或对数组元素做些什么。使用方法map!
像:
a = ["foo", "foo", "foo"]
=> ["foo", "foo", "foo"]
a.map! { |x| x + "bar" }
=> ["foobar", "foobar", "foobar"]
b = ["foo"]*3
=> ["foo", "foo", "foo"]
b.map! { |x| x + "bar" }
=> ["foobar", "foobar", "foobar"]