Ruby中的破坏性和非破坏性方法

时间:2020-07-03 15:52:22

标签: ruby

我不久前问了这个问题-"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!是非破坏性的吗?还是这里发生了我想念的事情。

1 个答案:

答案 0 :(得分:2)

重要的是要记住Ruby中有哪些变量,而这些变量实际上是对对象的引用,或更准确地说,是带有积分引用计数的精美指针。

这意味着str之类的东西只是对某个String对象的引用。像upcase!这样的方法会更改该对象。像upcase这样的方法不会,它返回一个新对象。文档中对这些差异进行了说明,您必须检查该文档以确保正确。单独使用!是远远不够的,因为Array#pop之类的方法会更改数组并且没有这种修饰。

当您编写这样的行时:

str + '?'

确实创建了一个新对象,但是由于您从未真正将其捕获到变量中或将其用作参数,因此将其立即丢弃。

您的意思是:

str = str + '?'

或更简洁地说:

str += '?'

这两个都创建一个新对象,然后将str引用到这个新对象。

相关问题