gpt4 book ai didi

ruby - 在 Ruby 中创建副本

转载 作者:太空宇宙 更新时间:2023-11-03 18:17:32 25 4
gpt4 key购买 nike

我以下面的代码为例。

a = [2]
b = a
puts a == b
a.each do |num|
a[0] = num-1
end
puts a == b

我要b引用a的值,以及 b 的值a 时不要更改已更改。(第二个 puts 应返回 false)。提前谢谢你。

编辑-

user2864740 发布的答案似乎适用于我给出的示例。但是,我正在开发一个数独解决程序,但它似乎在那里不起作用。

@gridbylines = [[1,0,0,9,2,0,0,0,0],
[5,2,4,0,1,0,0,0,0],
[0,0,0,0,0,0,0,7,0],
[0,5,0,0,0,8,1,0,2],
[0,0,0,0,0,0,0,0,0],
[4,0,2,7,0,0,0,9,0],
[0,6,0,0,0,0,0,0,0],
[0,0,0,0,3,0,9,4,5],
[0,0,0,0,7,1,0,0,6]]

save = Array.new(@gridbylines) #or @gridbylines.dup
puts save == @gridbylines #returns true
puts save.equal?(@gridbylines) #returns false
@gridbylines[0][0] = 'foo'
puts save.equal?(@gridbylines) #returns false
puts save == @gridbylines #returns true, but I want "save" not to change when I change "@gridbylines"

这是否与我使用的全局变量或我使用的 Ruby 版本有关,或者甚至因为它是一个与前面示例不同的多维数组有关?

最佳答案

变量名称或“引用”对象1。在上面的代码中,相同 对象(它有两个名称,ab)正在被更改。

在这种情况下,一个简单的解决方案是对原始数组对象制作(浅)副本,例如b = a.dupb = Array.new(a) . (对于浅拷贝,数组中的元素也是共享的,并且会显示与原始问题相似的音素,除非它们被[递归]复制,等等。2)

a = [2]
b = Array.new(a) # create NEW array object, a shallow-copy of `a`
puts a == b # true (same content)
puts a.equal?(b) # false (different objects)
a.each do |num|
a[0] = num-1 # now changing the object named by `a` does not
# affect the object named by `b` as they are different
end
puts a == b # false (different content)

以及这种“命名”现象的一个孤立示例(参见 different equality forms):

a = []

b = a # assignment does NOT make a copy of the object
a.equals?(b) # true (same object)

c = a.dup # like Array.new, create a new shallow-copy object
a.equals?(c) # false (different object)

1 我发现将变量称为名称是最统一的说法,因为这样的概念可以跨多种语言应用——这里的关键是任何对象都可以有一个或多个名称,就像一个人可以有很多昵称。如果一个对象的名称为零,那么它就不再是强可达的,就像一个人一样,会被遗忘。

但是,另一种查看变量(命名对象)的方法是它们保存引用值,其中引用值标识一个对象。这导致诸如

之类的措辞
  • “变量 a 包含对对象 x 的引用 [值]” - 或者,
  • “变量 a 引用/引用对象 x”——或者,如我所愿,
  • “变量 a 是对象 x 的名称”。

对于大小写或不可变的“原始”或“直接”值,底层机制略有不同,但是,由于不可变,对象值无法更改,并且这种缺乏共享对象的性质不会表现出来。


另见:


2 根据嵌套数组的更新问题,这由先前的规则解释 - 变量(好吧,实际上是表达式)仍然命名为 shared 对象。在任何情况下,“克隆数组的数组”(到两个级别,尽管不是递归的)的一种方法是使用:

b = a.map {|r| r.dup}

这是因为 Array#map 返回一个包含映射值的新数组,在本例中,映射值是相应嵌套数组的副本(浅克隆)。

参见 How to create a deep copy of an object in Ruby?对于其他“深度 [er] 复制”方法 - 特别是如果数组(或影响可变对象)嵌套到 N 级。

关于ruby - 在 Ruby 中创建副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23791044/

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