2011-12-20 76 views
33

考慮下面的代碼:Ruby中的字符串是否可變?

$ 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) 

好像單個字符是可以改變的W/O創建一個新的字符串。但是附加到字符串顯然會創建一個新的字符串。

是在Ruby中的字符串可變的?

+2

是的,通過瑣碎的搜索交代。 http://stackoverflow.com/questions/2608493/why-did-matz-choose-to-make-strings-mutable-by-default-in-ruby – 2011-12-20 18:43:18

+0

@DaveNewton:不是很好它是多麼容易在SO上尋找訣竅,因爲你幾乎可以依靠谷歌首先提出的SO話題? – 2011-12-20 18:45:15

+4

'+'連接並將返回一個新的字符串。 '<<'正在附加,並將附加到給定的字符串對象(不會創建一個新對象)。 – Chad 2011-12-20 18:45:43

回答

37

是,在Ruby中的字符串,不像在Python,是可變的。

s += "hello"附加"hello"s - 一個全新的字符串對象被創建。要追加到「到位」的字符串,使用<<,像:

s = "hello" 
s << " world" 
s # hello world 
+3

在Ruby中將'a + = b'想成'a = a + b'是否合理?這將清楚爲什麼's + =「hello」'創建一個新的字符串。 – emlai 2016-01-08 17:52:36

+1

@tuple_cat是的,這就是'+ ='的實現方式,因此重新定義'+'會得到一個重定義的'+ ='。 – YoTengoUnLCD 2016-07-12 19:08:49

8

Ruby String追加不+=,它是<<

所以,如果你改變+=<<你的問題

+3

+1。正如http://www.rubyfleebie.com/appending-to-a-string/所解釋的那樣,「'+ ='將創建一個新的String實例並將其分配給您的左對象。另一方面,'<< '會將新字符串直接追加到已存在的左對象中。「 – ruakh 2011-12-20 18:45:01

11
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 

所以,字符串是可變的,但+=運營商創建一個被單獨處理新的字符串。 <<保持老

6

字符串在Ruby中是可變的,但你可以凍結改變它。

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

從我可以做的this pull request,它將Ruby的3.0成爲可能添加一個「神奇的意見」,這將使所有的字符串不變,而不是可變的。

因爲看起來你必須明確地添加這個評論,它似乎是「字符串可變的默認?」的答案。仍然是肯定的,但有條件的是 - 取決於你是否將魔術評論寫入了你的劇本。

編輯

我指出這個bug/issue on Ruby-Lang.org是明確指出一些類型的Ruby 3.0字符串其實會默認爲不可變的。

1

Ruby字符串是可變的。但是你需要使用< <來連接而不是+。
事實上連接字符串與
+運算符(不可變),因爲它創建新的字符串對象。
< <操作者(可變)因爲它在同一個對象變化。

相關問題