我正在使用 RuboCop 默认强制执行的 # frozen_string_literal: true
魔术注释,并且无法向字符串追加内容:
string = 'hello'
string << ' world'
因为它会出现错误信息:
无法修改冻结的字符串 (RuntimeError)
我正在使用 RuboCop 默认强制执行的 # frozen_string_literal: true
魔术注释,并且无法向字符串追加内容:
string = 'hello'
string << ' world'
因为它会出现错误信息:
无法修改冻结的字符串 (RuntimeError)
+
,像这样:string = +'hello'
string << ' world'
puts(string)
你好世界
String.new('hello')
或 'hello'.dup
。 - cremno+=
:s = 'H'
s += 'ello
=> "你好"
当启用# frozen_string_literal:true
时,您不能“更改”任何字符串。
需要证明吗? 使用以下脚本...
# 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'
来解决这个问题。
为什么?因为+=
是一种简写的重新赋值方式。与变异不同,+=
创建一个全新的字符串(具有全新的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: true
时,您可以使用 string << 'string'
而不是您提到的 string += 'string'
来“改变”字符串。 - Iulian Onofrei# frozen_string_literal: true
str = 'hello'
str << ' world'
跟踪最近的调用(上次):
frozen_strings.rb:4::无法修改冻结字符串(FrozenError)
- Conturbo# frozen_string_literal: true
时无法更改字符串,但在您的第一条评论中,您断言可以这样做。 - Conturbo= +
进行初始化,而不是简单地使用=
, 即使frozen_string_literal
设置为true
,你仍然可以改变字符串。 - Iulian Onofrei