我正在通过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