我不久前问了这个问题-"Does 'upcase!' not mutate a variable in Ruby?
"。作为后续,我对代码进行了一些更改,但仍然不确定发生了什么。 +
为什么不修改str
指向的对象?我不会再次重新分配str
,对吧?
def change_string(str)
str + "?"
str.upcase!
end
phrase = "what time is it"
change_string(phrase)
puts phrase
该短语为大写字母,但未添加问号。如果我删除大写对象的最后一行,则“?”附加。为什么是这样?是因为+
是非破坏性的,而upcase!
是非破坏性的吗?还是这里发生了我想念的事情。
答案 0 :(得分:2)
重要的是要记住Ruby中有哪些变量,而这些变量实际上是对对象的引用,或更准确地说,是带有积分引用计数的精美指针。
这意味着str
之类的东西只是对某个String对象的引用。像upcase!
这样的方法会更改该对象。像upcase
这样的方法不会,它返回一个新对象。文档中对这些差异进行了说明,您必须检查该文档以确保正确。单独使用!
是远远不够的,因为Array#pop
之类的方法会更改数组并且没有这种修饰。
当您编写这样的行时:
str + '?'
该确实创建了一个新对象,但是由于您从未真正将其捕获到变量中或将其用作参数,因此将其立即丢弃。
您的意思是:
str = str + '?'
或更简洁地说:
str += '?'
这两个都创建一个新对象,然后将str
引用到这个新对象。