gpt4 book ai didi

ruby - 对象分配和指针

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

我对 Ruby 中的对象分配和指针有点困惑,编写了这段代码来测试我的假设。

class Foo
attr_accessor :one, :two
def initialize(one, two)
@one = one
@two = two
end

end

bar = Foo.new(1, 2)
beans = bar

puts bar
puts beans

beans.one = 2
puts bar
puts beans
puts beans.one
puts bar.one

我曾假设,当我将 bar 分配给 beans 时,它会创建该对象的副本,并且修改一个不会影响另一个。唉,输出显示不是这样。

^_^[jergason:~]$ ruby test.rb 
#<Foo:0x100155c60>
#<Foo:0x100155c60>
#<Foo:0x100155c60>
#<Foo:0x100155c60>
2
2

我相信这些数字与对象的地址有关,并且它们对于 bean 和 bar 都是相同的,当我修改 beans 时,bar 也会改变,这不是我所期望的。看来我只是在创建一个指向该对象的指针,而不是它的副本。我需要做什么才能在分配时复制对象,而不是创建指针?

Array 类的测试也显示了一些奇怪的行为。

foo = [0, 1, 2, 3, 4, 5]
baz = foo
puts "foo is #{foo}"
puts "baz is #{baz}"
foo.pop
puts "foo is #{foo}"
puts "baz is #{baz}"

foo += ["a hill of beans is a wonderful thing"]
puts "foo is #{foo}"
puts "baz is #{baz}"

这会产生以下奇怪的输出:

foo is 012345
baz is 012345
foo is 01234
baz is 01234
foo is 01234a hill of beans is a wonderful thing
baz is 01234

这让我大吃一惊。在 foo 上调用 pop 也会影响 baz,因此它不是副本,但将某些内容连接到 foo 上只会影响 foo,而不会影响 baz。那么我什么时候处理原始对象,什么时候处理副本?在我自己的类里面,我怎样才能确保作业是复制的,而不是做指针?帮助这个困惑的人。

最佳答案

这个问题有很多问题。要知道的主要事情是赋值从不在 ruby​​ 中创建副本,但方法通常返回新对象而不是修改现有对象。对于像 Fixnums 这样的不可变对象(immutable对象),您可以忽略它,但是对于像数组或 Foo 实例这样的对象,要制作一个副本,您必须执行 bar.dup

至于数组示例,foo += 没有连接到存储在 foo 中的数组,为此您可以执行 foo.concat([ 'a'])。相反,它正在创建一个新数组并将 foo 分配给它。 Array 类的文档提到了哪些方法会就地改变数组,哪些方法会返回一个新数组。

关于ruby - 对象分配和指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2635156/

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