Ruby中的字符串是否可变?

Sun*_*day 34 ruby string mutable immutability

请考虑以下代码:

$ 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)
Run Code Online (Sandbox Code Playgroud)

似乎可以在不创建新字符串的情况下更改单个字符.但是,附加到字符串显然会创建一个新字符串.

Ruby中的字符串是否可变?

Mar*_*oda 45

是的,与Python不同,Ruby中的字符串是可变的.

s += "hello"不是追加"hello"s-一个全新的字符串对象被创建.要附加到"就地"字符串,请使用<<,如下所示:

s = "hello"
s << "   world"
s # hello world
Run Code Online (Sandbox Code Playgroud)

  • 在Ruby中将"a + = b"视为"a = a + b"是否有意义?这将清楚地说明为什么`s + ="hello"`创建一个新字符串. (3认同)
  • @tuple_cat 是的,这就是`+=` 的实现方式,因此重新定义`+` 会产生重新定义的`+=`。 (2认同)

zed*_*xff 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 
Run Code Online (Sandbox Code Playgroud)

所以,字符串是可变的,但+=运算符创建一个新的字符串.<<老了


Ole*_*eev 8

附加在Ruby String中不是+=,它是<<

因此,如果您更改+=<<您的问题,请自行解决

  • +1.正如在http://www.rubyfleebie.com/appending-to-a-string/中所解释的那样,"`+ =`将创建一个新的String实例,并将它分配给你的左对象.另一方面,`<< `会将新字符串直接附加到已存在的左对象中." (3认同)

hip*_*ker 7

Ruby中的字符串是可变的,但您可以通过冻结来更改它.

irb(main):001:0> s = "foo".freeze
=> "foo"
irb(main):002:0> s << "bar"
RuntimeError: can't modify frozen String
Run Code Online (Sandbox Code Playgroud)