【发布时间】:2013-04-10 12:38:29
【问题描述】:
我是 Scala 新手,所以我想了解为什么对视图的调用会返回 IndexedSeqViewS 和类似类的实例。为什么每个操作都需要不同的类?
【问题讨论】:
标签: scala collections lazy-evaluation
我是 Scala 新手,所以我想了解为什么对视图的调用会返回 IndexedSeqViewS 和类似类的实例。为什么每个操作都需要不同的类?
【问题讨论】:
标签: scala collections lazy-evaluation
因为每个视图转换器操作(即生成新视图的操作,例如 map、filter 或 slice)都会创建一个以不同方式遍历基础集合的视图。
请注意,IndexedSeqViewS 不是该集合类的实际名称 - 它是 toString 返回的美化名称。
例如,Mapped 视图创建基础集合的视图,以便基础集合的每个元素都以某种方式进行转换。
这需要重新定义foreach,如下所示:
trait Mapped[B] extends Transformed[B] {
// ...
def foreach[U](f: B => U) {
for (x <- self)
f(mapping(x))
}
// ...
}
Filtered 视图需要在遍历时忽略一些元素:
trait Filtered extends Transformed[A] {
// ...
def foreach[U](f: A => U) {
for (x <- self)
if (pred(x)) f(x)
}
// ...
}
由于集合具有基于继承的设计,要覆盖foreach 的定义(以及apply、size 等其他方法),需要引入子类。在一些替代设计中,例如一个基于类型类的,可能必须引入一个单独的类型类来重新定义特定类型的foreach。
【讨论】:
Stream[T]操作是否有单独的类?
Stream 操作只有 2 个类——空流和流缺点。但是,这些操作总是返回一个Stream——并且每个流都使用相同的foreach 实现进行遍历。 *View 操作是独立于集合的——视图链中底层集合 (foreach) 的遍历根据先前调用的操作而变化——以及其他访问器操作(如 reduce、@987654342 @ 或 copyToArray) 以 foreach 的形式实现。
flatMapFilterGroupBySlice 表示所有视图转换包含所有可能的转换信息的方法。