Ruby对象引用

use*_*453 1 ruby string ruby-on-rails reference object

我在Ruby中遇到了一段令我困惑的代码片段.将其归结为下面的一个简单示例来说明.为什么sArr在第一种情况下没有自动更新其内容但在第二种情况下会发生?这些片段简短且不言自明,三个回归将两个场景分开.

2.0.0-p598 :068 > str = "Hello"
=> "Hello" 
2.0.0-p598 :069 > sArr = [str]
=> ["Hello"] 
2.0.0-p598 :070 > str = str.upcase
=> "HELLO" 
2.0.0-p598 :071 > str
=> "HELLO" 
2.0.0-p598 :072 > sArr
=> ["Hello"]  # Why is this not ["HELLO"] like in the sequence below?
2.0.0-p598 :073 > 
2.0.0-p598 :074 >   
2.0.0-p598 :075 >   
2.0.0-p598 :076 >   str = "Hello"
=> "Hello" 
2.0.0-p598 :077 > sArr = [str]
=> ["Hello"] 
2.0.0-p598 :078 > str.upcase!
=> "HELLO" 
2.0.0-p598 :079 > sArr
=> ["HELLO"] 
Run Code Online (Sandbox Code Playgroud)

Mat*_*att 5

这是因为创建了一个新的String实例str = str.upcase但是没有str.upcase!:

str = "Hello"
str.object_id
# => 70132476337960 
str = str.upcase
# => "HELLO" 
str.object_id
# => 70132476374360 (new instance)

str = "Hello"
str.object_id
# => 70132476415240 
str.upcase!
# => "HELLO" 
str.object_id
# => 70132476415240 (same instance)
Run Code Online (Sandbox Code Playgroud)

sArr不受影响,str = str.upcase因为它持有对初始的引用"Hello".分配给str不会更改对象,sArr如果你做的话str = 'World'.相反,str.upcase!修改由持有的实例sArr.