为啥 String::sub!() 会更改 Ruby 中克隆对象的原始内容?

Posted

技术标签:

【中文标题】为啥 String::sub!() 会更改 Ruby 中克隆对象的原始内容?【英文标题】:Why does String::sub!() change the original of a cloned object in Ruby?为什么 String::sub!() 会更改 Ruby 中克隆对象的原始内容? 【发布时间】:2011-05-11 12:11:51 【问题描述】:

我的 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 来进行深层复制是个好主意吗?

【问题讨论】:

【参考方案1】:

newFreqfreq 的浅拷贝。这意味着存储在newFreq 中的每个引用都指向对象,就像存储在freq 中的引用一样。您可以单独更改引用指向的位置 (newFreq.name = newFreq.name.sub 'f','newF'),但如果您调用改变对象的方法,newFreqfreq 都会受到影响。

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

【讨论】:

【参考方案2】:

Object#clone 方法执行浅拷贝。您需要深拷贝才能完成工作。

关注this link,了解 Ruby 中的深拷贝。

【讨论】:

以上是关于为啥 String::sub!() 会更改 Ruby 中克隆对象的原始内容?的主要内容,如果未能解决你的问题,请参考以下文章

为啥更改 innerText 值也会更改 innerHTML?

为啥覆盖会更改列名

为啥在其中创建新文件时目录的更改时间(ctime)会更改?

为啥 sudo 会更改 PATH?

为啥日期会更改 1 天?

为啥我的 UICollectionViewCells 在动画超级视图约束更改时会更改 alpha 值?