代码之家  ›  专栏  ›  技术社区  ›  Jamison Dance

对象分配和指针

  •  6
  • Jamison Dance  · 技术社区  · 14 年前

    我对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分配给bean时,它将创建对象的副本,修改其中一个不会影响另一个。唉,产量却显示了不同的结果。

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

    我相信这些数字与对象的地址有关,bean和bar的数字是一样的,当我修改bean时,bar也会发生变化,这不是我所期望的。似乎我只是在创建指向对象的指针,而不是对象的副本。要在分配时复制对象,而不是创建指针,我需要做什么?

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

    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
    

    这打动了我的心。调用pop-on-foo也会影响baz,所以它不是一个副本,但是将某些内容连接到foo上只会影响foo,而不是baz。那么,我什么时候处理原始对象,什么时候处理副本?在我自己的类中,如何确保分配是复制的,并且不生成指针?帮这个迷茫的家伙出去。

    4 回复  |  直到 12 年前
        1
  •  11
  •   mckeed    14 年前

    这个问题有很多问题。最重要的是 赋值从不在Ruby中生成副本,但方法通常返回新对象,而不是修改现有对象。 . 对于像fixnums这样的不可变对象,可以忽略它,但是对于数组或foo实例这样的对象,要制作副本,必须执行以下操作 bar.dup .

    对于数组示例, foo += 未连接到存储在 foo 做你会做的事 foo.concat(['a']) . 相反,它正在生成一个新的数组并分配 对此。array类的文档提到了哪些方法可以就地改变数组,哪些方法返回新的数组。

        2
  •  3
  •   hermannloose    14 年前

    + - 在里面 Array 每次返回 新的 数组中填充了各自的内容,所以 foo += [...] 不影响 baz 是正常的。试试 << 运算符开启 foo 结果是 巴兹 看到同样的变化。

    我不知道Ruby如何在内部处理其他事情,但您可以尝试使用 one.clone two.clone 在里面 Foo#initialize .

        3
  •  2
  •   Luisa    12 年前

    你从不处理复印件。它在内存中是同一个对象,但是您只声明了对它的两个引用:在第一个示例中:bar和beans指向内存中的同一个对象;在第二个示例中:foo和baz最初指向内存中的同一数组。

    查看2个图片/图片,在Java教程页面中解释机制(它与Ruby相同)和2个图片,比任何解释都要值钱: http://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html

        4
  •  0
  •   SSP    12 年前

    basicly ruby使用的是引用指针,所以当您更改一个对象时,另一个对象也会受到影响。