为什么Scala集合API的层次结构图中的根目录中存在Traversable和Iterable?

时间:2017-11-06 10:18:19

标签: scala

Traversable是集合层次结构的顶层。它的主要方法是'foreach'所以它允许为集合的每个元素做一些事情。

Iterable可以创建一个Iterator,基于该Iterator可以实现foreach。这定义了元素的某些顺序,尽管每个迭代器的顺序可能会改变。

从Traversable扩展的唯一类是Iterable。那么为什么不将这两个类统一为一个类?

1 个答案:

答案 0 :(得分:3)

嗯,正如您自己观察到的那样,您始终可以foreach来实施iterator。但事实并非如此:如果您只有iterator,则通常无法实现foreach。唯一的方法是运行foreach直到它完成,将元素收集到一个单独的集合中,并返回此集合的迭代器。这对于大型集合来说是低效的,对于无限集合来说是完全不可能的。

但是,标准库确实不包含Traversable但不包含Iterable的任何内容,实际上很难提出示例。基本上,一个东西可以是Traversable而不是Iterable,如果它是允许迭代的东西,但它也需要保持一些迭代状态,这在迭代器中是不可行的外化。一个例子可能是SAX API的一些包装器,它提供了基于推送的XML解析器。这些解析器是回调驱动的;您提供对解析器的回调,它会自动运行直到被解析的文档结束,在回调对象上调用与XML结构的各种元素相对应的方法。为SAX解析器创建Traversable包装器几乎是微不足道的;创建Iterable包装器是不可能的(不首先收集结果,正如我上面所说的那样,效率非常低)。另一方面,JavaSE还提供StAX API,它基本上是基于迭代器的,因此StAX解析器的Iterable包装器也可以很容易地实现。

实际上,Scala的作者也意识到Traversable并没有那么有用。这就是redesigned collections library缺少Traversable的原因,这将在Scala 2.13中发布。关于Traversable为什么不好的另一种观点可以找到here