如何在 Ruby 中创建可变字符串?

How do I create a mutable string in Ruby?

我正在使用 RuboCop 默认强制执行的 # frozen_string_literal: true 魔术注释,我无法将某些内容附加到字符串:

string = 'hello'

string << ' world'

因为它出错了:

can't modify frozen String (RuntimeError)

您在字符串前添加一个 +,例如:

string = +'hello'

string << ' world'

puts(string)

hello world

您也可以使用 +=:

s = 'H'
s += 'ello

=> "Hello"

启用# frozen_string_literal: true后,您不能'mutate'任何字符串。

需要证据吗? 使用以下脚本...

# frozen_string_literal: true

str = 'hello'
str << ' world'

你会得到以下错误...

Traceback (most recent call last):
frozen_strings.rb:4:in `<main>': can't modify frozen String (FrozenError)

'Mutate'表示改变对象的值。 因此,您的示例失败,因为 << 改变了字符串,并且它正在改变您的字符串 string 因为您使用的是 << 运算符。

需要证据吗? 进入irb! 输入以下内容:

str = 'hello' # => 'hello'
obj_id1 = str.object_id # => some number, ex: 12345
str << ' world' # => 'hello world'
obj_id2 = str.object_id # => some number, ex: 12345
obj_id1 == obj_id2 # this should return true, proving that you mutated the object

但是,您可以使用 str += ' world' 来解决这个问题。 为什么?因为 += 是 shorthand 重新赋值。 += 没有改变,而是创建了一个全新的字符串(带有一个全新的 object_id)并将其存储在相同的变量名下(在本例中为 str)。

需要证明吗?在 irb 中查看!

str = 'hello' # => 'hello'
obj_id1 = str.object_id # => some number, ex: 12345
str += ' world' # => ' world'
obj_id2 = str.object_id # => some other number, ex: 356456345
obj_id1 == obj_id2 # => this returns false!

如果有帮助请告诉我!

frozen_string_literal 用于字符串文字。要创建可变字符串实例,请使用 String#new 或在字符串文字前添加 +

# frozen_string_literal: true
'foo'.frozen? # => true
String.new.frozen? # => false
(+'foo').frozen? # => false