为什么要返回一个普查员?

pgu*_*rio 10 ruby arrays enumerator

我很好奇为什么ruby返回一个Enumerator而不是一个Array,看起来似乎是一个明显的选择.例如:

'foo'.class
# => String
Run Code Online (Sandbox Code Playgroud)

大多数人认为String是一个字符数组.

'foo'.chars.class
# => Enumerator
Run Code Online (Sandbox Code Playgroud)

那么为什么String #chars会返回一个Enumerable而不是一个Array呢?我假设有人对此进行了大量的思考,并认为Enumerator更合适,但我不明白为什么.

Rea*_*onk 7

如果你想要一个数组,请致电#to_a.Enumerable和之间的区别Array是,一个是懒惰而另一个是渴望.这是很好的旧内存(懒惰)与cpu(急切)优化.显然他们选择了懒惰,也因为

str = "foobar"
chrs = str.chars
chrs.to_a # => ["f", "o", "o", "b", "a", "r"]
str.sub!('r', 'z')
chrs.to_a # => ["f", "o", "o", "b", "a", "z"]
Run Code Online (Sandbox Code Playgroud)


Mar*_*eed 5

  1. 抽象 - 事物可能是一个数组,这是一个你不关心许多用例的实现细节.对于那些你做的人,你可以随时调用.to_aEnumerable来获取一个.

  2. 效率 - 枚举器是懒惰的,因为Ruby不必一次构建整个元素列表,但可以根据需要一次一个地构建.所以实际上只计算了你需要的数字.当然,这会导致每个项目的开销更大,所以这是一个权衡.

  3. 可扩展性 - chars返回Enumerable 的原因是因为它本身是作为枚举器实现的; 如果你传递一个块,那么每个字符将执行一次该块.这意味着没有必要,例如.chars.each do ... end; 你可以这样做.chars do ... end.这使得在字符串的字符上构造操作链变得容易.


ste*_*lag 2

这完全符合1.9的精神:尽可能返回枚举数。String#bytes、String#lines、String#codepoints 以及 Array#permutation 等方法都返回一个枚举器。

在 ruby​​ 1.8 中,String#to_a 产生了一个行数组,但该方法在 1.9 中消失了。