为什么Ruby字符串通过一个操作和另一个操作的引用按值更改

时间:2013-10-26 18:43:19

标签: ruby

以下代码:

 test_1 = "my test string"
 test_2 = test_1
 test_2[3] = "B"
 puts test_1
 puts test_2

 test_1 = "my test string"
 test_2 = test_1
 test_2 = test_2 + ""
 test_2[3] = "B"
 puts test_1
 puts test_2

产生以下结果:

 my Best string
 my Best string
 my test string
 my Best string

有些人可以向我解释为什么在第一种情况下两个字符串都被改变了(好像test_2是通过引用分配的)但是在第二种情况下只有test_2发生了变化(好像是值)?

2 个答案:

答案 0 :(得分:3)

以下是澄清:

test_1 = "my test string"
test_2 = test_1

test_2.object_id # => 83607730
test_1.object_id # => 83607730

test_2 = test_2 + ""

test_2.object_id # => 83606390
test_1.object_id # => 83607730

String#+创建了一个新对象。 因此test_2[3] = "B""B"添加到test_2引用的新对象。它不会更改对象,其引用由test_1开头。以下情况并非如此:

test_1 = "my test string"
test_2 = test_1

test_2.object_id # => 70466640
test_1.object_id # => 70466640

此处test_2test_1都包含对同一对象的引用。因此,当您执行test_2[3] = "B"时,它基本上在由局部变量test_1test_2引用的同一对象中进行更改。

答案 1 :(得分:3)

在Ruby中声明"test"时,会创建一个新的String对象。

"test".object_id   # => 9157960
"test".class       # => String

当您为变量指定字符串时,将变量指向赋值另一侧的字符串对象。

看看以下内容:

# Point variable to first String object.
a = "test"         # => "test"
a.object_id        # => 9307800

# Point variable to second String object.
b = "test"         # => "test"
b.object_id        # => 9307760
a.equal?(b)        # => false

# Point variable to first String object.
c = a              # => "test"
c.object_id        # => 9307800
a.equal?(c)        # => true

所以当你在这里操纵a时,你会操纵c指向的对象。