我正在通過Project Euler我的方式工作,並遇到了一個有點令人驚訝的遺漏:沒有String#shift
,unshift
,push
或pop
。我假定一個String被認爲是一個像Array這樣的「順序」對象,因爲它們共享索引和迭代的能力,並且這包括能夠輕鬆更改對象的開始和結束的能力。爲什麼沒有String#shift()?
我知道有辦法創造相同的效果,但有沒有一個特定的原因,字符串確實不是有這些方法?
我正在通過Project Euler我的方式工作,並遇到了一個有點令人驚訝的遺漏:沒有String#shift
,unshift
,push
或pop
。我假定一個String被認爲是一個像Array這樣的「順序」對象,因爲它們共享索引和迭代的能力,並且這包括能夠輕鬆更改對象的開始和結束的能力。爲什麼沒有String#shift()?
我知道有辦法創造相同的效果,但有沒有一個特定的原因,字符串確實不是有這些方法?
字符串不充當1.9中的可枚舉對象,因爲它被認爲太混亂以至於無法確定它將成爲一個列表:
不是Ruby的貢獻者,我不能說他們的設計目標,但從經驗來說,我不認爲字符串被認爲是'順序'的對象;它們以可以提示順序行爲的方式變化,但大多數情況下它們都是以原子方式處理的。例子:在Ruby 1.9中,String
不再混合Enumerable
。
>> mystring = "abcdefgh"
=> "abcdefgh"
>> myarray = mystring.split("")
=> ["a", "b", "c", "d", "e", "f", "g", "h"]
>> myarray.pop
=> "h"
>> mystring = myarray.join
=> "abcdefg"
這應該這樣做,你wouldhave將其轉換爲一個數組,然後回雖然
UPDATE:
使用String#chop!
和Stirng#<<
>> s = "abc"
=> "abc"
>> s.chop!
=> "ab"
>> s
=> "ab"
>> s<<"def"
=> "abdef"
>> s
=> "abdef"
>>
至少在1.9.2中,你可以處理像數組這樣的字符串。
ruby-1.9.2-p290 :001 > "awesome"[3..-1] => "some"
所以,如果你想要做一個排序字符左移,只是使用[1 ..- 1]
ruby-1.9.2-p290 :003 > "fooh!"[1..-1] => "ooh!"
可能是因爲如果字符串有這些方法,人們會使用它們。這將是一件壞事。另見:「成功之坑」。你不希望最簡單的方法也是錯誤的方式。 – Jimmy 2011-02-10 23:31:48
爲什麼它會是一件壞事? – Zabba 2011-02-10 23:32:26
@Zabba:在很多語言中,字符串都是不可變的。這可以讓你擺脫像國際表這樣的詭計,但也意味着如果你堅持對字符串進行大量變異,這是非常低效的。最經典的例子就是.NET的「gotcha」面試問題「以下代碼出了什麼問題?」 (這就像`bar =「」; foreach(var foo in frob)bar + = foo;`) – Jimmy 2011-02-10 23:45:26