2011-02-10 36 views
13

我正在通过Project Euler我的方式工作,并遇到了一个有点令人惊讶的遗漏:没有String#shift,unshift,pushpop。我假定一个String被认为是一个像Array这样的“顺序”对象,因为它们共享索引和迭代的能力,并且这包括能够轻松更改对象的开始和结束的能力。为什么没有String#shift()?

我知道有办法创造相同的效果,但有没有一个特定的原因,字符串确实不是有这些方法?

+1

可能是因为如果字符串有这些方法,人们会使用它们。这将是一件坏事。另见:“成功之坑”。你不希望最简单的方法也是错误的方式。 – Jimmy 2011-02-10 23:31:48

+0

为什么它会是一件坏事? – Zabba 2011-02-10 23:32:26

+0

@Zabba:在很多语言中,字符串都是不可变的。这可以让你摆脱像国际表这样的诡计,但也意味着如果你坚持对字符串进行大量变异,这是非常低效的。最经典的例子就是.NET的“gotcha”面试问题“以下代码出了什么问题?” (这就像`bar =“”; foreach(var foo in frob)bar + = foo;`) – Jimmy 2011-02-10 23:45:26

回答

11

字符串不充当1.9中的可枚举对象,因为它被认为太混乱以至于无法确定它将成为一个列表:

  • 字符/码点列表?
  • 字节列表?
  • 行列表?
5

不是Ruby的贡献者,我不能说他们的设计目标,但从经验来说,我不认为字符串被认为是'顺序'的对象;它们以可以提示顺序行为的方式变化,但大多数情况下它们都是以原子方式处理的。例子:在Ruby 1.9中,String不再混合Enumerable

5
>> 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" 
>> 
2

至少在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!" 
相关问题