0

以下代码:

 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 更改(好像按值)?

4

2 回答 2

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_1和引用的同一对象中进行更改test_2

于 2013-10-26T18:49:23.030 回答
3

当您"test"在 Ruby 中声明时,这会创建一个新的 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指向的对象。

于 2013-10-26T19:14:51.697 回答