我试图弄清楚为什么以下代码不会返回相同的结果:
代码1
p0 = "hello"
a = []
b = p0
1.upto(5) do |i|
b.insert(2,"B")
a.push b
end
a => ["heBBBBBllo", "heBBBBBllo", "heBBBBBllo", "heBBBBBllo", "heBBBBBllo"]
代码2
p0 = "hello"
a = []
b = p0
1.upto(5) do |i|
b.insert(2,"B")
a.push b.inspect
end
a => ["\"heBllo\"", "\"heBBllo\"", "\"heBBBllo\"", "\"heBBBBllo\"", "\"heBBBBBllo\""]
我需要的是Code 2的结果,但我不需要像inspect方法那样的转义字符。
老实说,我真的不明白为什么检查方法有效,为什么在代码1中没有。 看起来在代码1中,“b”用作指针,每次更新时,所有“链接”-b都会更新。
任何线索??
提前谢谢。
答案 0 :(得分:3)
在代码1中,您正在推送对同一对象的引用。该数组将包含对同一事物的多个引用。
在代码2中,您将在不同的时刻推送inspect
输出。该数组将包含inspect
返回字符串的历史记录。
答案 1 :(得分:1)
p0 = "hello"
a = []
b = p0
1.upto(5) do |i|
b.insert(2,"B")
a.push b.clone
end
答案 2 :(得分:0)
'b'是一个字符串,它是一个对象。插入字母时,它会修改对象。
在CODE 1中,同一个对象b被多次推入数组,并被多次修改。
但是,b.inspect返回一个新字符串。所以在CODE 2中,每次迭代都会将一个新字符串推送到数组中,而新字符串是“b”在时间上看的快照。
你可以改用a.push b.dup,它可以在不改变格式的情况下创建b的副本。
答案 3 :(得分:0)
似乎在代码1中,“b”用作指针,并且每次都使用 它已更新,所有“链接”-b都会更新。
正确!在第一种情况下,您将b
推入数组五次,结果是a
包含五个指向b
的指针。在第二种情况下,您正在推送b.inspect
- 这是与b
不同的对象。
修复第一个示例的最简单方法是改为调用a.push b.dup
,这会创建b
的副本,不会受到b
的未来更改的影响。