我现在正在完成一个教程,我想了解发生以下情况的原因:
original_string = "Hello, "
hi = original_string
there = "World"
hi += there
assert_equal "Hello, ", original_string
original_string = "Hello, "
hi = original_string
there = "World"
hi << there
assert_equal "Hello, World", original_string
为什么+=
对original_string
没有影响,<<
呢?我绝对肯定第二种情况也会等于"Hello, "
,但事实并非如此。
hi = original string
似乎将original_string
的值复制到hi
,但第二个示例中的hi = original string
似乎将hi
设置为指向与original string
相同的字符串。我猜在幕后会有一些关于是复制值还是复制引用的隐含决定......或者什么。
答案 0 :(得分:3)
<<
会改变原始对象,而+=
会创建一个副本并返回该对象。
请参阅以下相应字符串的object_id
:
2.1.1 :029 > original_string = "Hello, "
=> "Hello, "
2.1.1 :030 > hi = original_string
=> "Hello, "
2.1.1 :031 > there = "World"
=> "World"
2.1.1 :032 > original_string.object_id
=> 70242326713680
2.1.1 :033 > hi.object_id
=> 70242326713680
2.1.1 :034 > hi += there
=> "Hello, World"
2.1.1 :035 > hi.object_id
=> 70242325614780
请注意第35行object_id
上的不同hi
。在上面的示例中将hi
重置为original_string
并使用<<
后,它会修改同一个对象。
答案 1 :(得分:3)
在这两个示例中,hi = original_string
复制了引用。
但是,对于+=
,您重新分配hi
以指向新字符串,即使变量名称相同。
这是因为hi += there
在解释器中扩展为表达式hi = hi + there
。
在此操作之前,hi
和original string
共享对同一字符串对象的引用。在扩展表达式中进行=
操作后,hi
现在引用新创建的hi + there
字符串结果。
在表达式hi << there
中,没有任何内容可以改变hi
引用的对象。它引用与original_string
相同的字符串,因此hi
和original_string
都反映了更改(当然这是因为它们都引用了相同的字符串对象)。 / p>
答案 2 :(得分:1)