请考虑以下代码:
$ irb
> s = "asd"
> s.object_id # prints 2171223360
> s[0] = ?z # s is now "zsd"
> s.object_id # prints 2171223360 (same as before)
> s += "hello" # s is now "zsdhello"
> s.object_id # prints 2171224560 (now it's different)
似乎可以在不创建新字符串的情况下更改单个字符。但是,附加到字符串显然会创建一个新字符串。
Ruby中的字符串是否可变?
答案 0 :(得分:43)
是的,与Python不同,Ruby中的字符串是可变的。
s += "hello"
不将"hello"
附加到s
- 创建一个全新的字符串对象。要附加到“就地”字符串,请使用<<
,例如:
s = "hello"
s << " world"
s # hello world
答案 1 :(得分:13)
ruby-1.9.3-p0 :026 > s="foo"
=> "foo"
ruby-1.9.3-p0 :027 > s.object_id
=> 70120944881780
ruby-1.9.3-p0 :028 > s<<"bar"
=> "foobar"
ruby-1.9.3-p0 :029 > s.object_id
=> 70120944881780
ruby-1.9.3-p0 :031 > s+="xxx"
=> "foobarxxx"
ruby-1.9.3-p0 :032 > s.object_id
=> 70120961479860
所以,字符串是可变的,但是+=
运算符会创建一个新的字符串。 <<
保持旧的
答案 2 :(得分:8)
Ruby String中的追加不是+=
,而是<<
因此,如果您将+=
更改为<<
,您的问题就会自行解决
答案 3 :(得分:7)
Ruby中的字符串是可变的,但您可以通过冻结来更改它。
irb(main):001:0> s = "foo".freeze
=> "foo"
irb(main):002:0> s << "bar"
RuntimeError: can't modify frozen String
答案 4 :(得分:3)
Ruby Strings是可变的。但是你需要使用&lt;&lt;连接而不是+。
实际上串联字符串与
+运算符(不可变)因为它会创建新的字符串对象
的&LT;&LT; operator(mutable)因为它在同一个对象中发生了变化。
答案 5 :(得分:0)
从this pull request开始,我可以在Ruby 3.0中添加一个&#34;魔术评论&#34;这将使所有字符串不可变,而不是可变。
因为看起来你必须明确地添加这个评论,所以&#34;的答案似乎是字符串可变默认?&#34;仍然是肯定的,但有条件的是 - 取决于你是否在你的剧本中写了魔法评论。
修改强>
我被指向这个bug/issue on Ruby-Lang.org明确指出Ruby 3.0中的某些类型的字符串实际上默认是不可变的。