破坏性的字符串赋值

时间:2017-07-07 03:29:13

标签: ruby string variable-assignment

在此代码中,

def string_assignment_original_name(name)
  save_name = name
  name.upcase!
  name
end

如果name = "Bob",则输出为"BOB"。同时在此代码中,

def string_assignment_save_name(name)
  save_name = name
  name.upcase!
  save_name
end

如果name = "Bob",则输出也是"BOB"

为什么会这样?

1 个答案:

答案 0 :(得分:3)

Ruby变量基本上是“对象引用”,它是内部的一种指针。 {I} namesave_name在就地修改之前和之后都引用相同的对象。

查看name.object_idsave_name.object_id的结果,看看它是如何发挥作用的,因为该方法是了解内部情况的窗口:

name = "bob"
name.object_id
# => ...2980

save_name = name
save_name.object_id
# => ...2980

name.upcase!
name.object_id
# => ...2980

现在,如果您通过.dup.clone等方法复制对象,或者通过其他进程创建一个全新的字符串,那么它就是一个新对象:

name = name.downcase
name.object_id
# => ...8480

现在你有两个对象在玩:

name.object_id
# => ...8480
save_name.object_id
# => ...2980

这些object_id值适用于所有意图,但每个对象实例都是唯一的。如果两个对象具有相同的object_id值,则它们是同一个对象。†

†​​从技术上讲,对象可以覆盖他们的object_id方法以返回其他内容,但这种情况很少见。