代码之家  ›  专栏  ›  技术社区  ›  bastibe

为什么是string::sub!()在Ruby中更改克隆对象的原始版本?

  •  5
  • bastibe  · 技术社区  · 14 年前

    我的Ruby代码中有一个结构看起来像这样

    Parameter = Struct.new(:name, :id, :default_value, :minimum, :maximum)
    

    稍后,我使用

    freq = Parameter.new('frequency', 15, 1000.0, 20.0, 20000.0)
    

    在某个时刻,我需要这个结构的精确副本,所以我调用

    newFreq = freq.clone
    

    然后,我改变 newFreq 的名字

    newFreq.name.sub!('f', 'newF')
    

    奇迹般地,它改变了 freq.name 也是!

    一个简单的作业 newFreq.name = 'newFrequency' 不改变 freq .

    这是应该的工作方式吗?

    编辑: 使用类而不是结构和重载是个好主意吗 clone 做一份深度复制?

    2 回复  |  直到 14 年前
        1
  •  10
  •   Ken Bloom    14 年前

    newFreq 是一个肤浅的副本 freq . 这意味着存储在 纽弗雷克 指向存储在中的对象 弗雷克 . 您可以更改引用独立指向的位置( newFreq.name = newFreq.name.sub 'f','newF' ,但是如果调用一个使对象发生变化的方法, 纽弗雷克 弗雷克 会受到影响。

    也见 http://en.wikipedia.org/wiki/Object_copy

        2
  •  8
  •   upriser    14 年前

    这个 Object#clone 方法执行浅复制。你需要 深拷贝 完成工作。

    跟随 this link 了解Ruby中的深度复制。