我读了
我想我有点处理canBuildFrom.
但后来我查看了源码TraversableView,我看到了:
object TraversableView {
class NoBuilder[A] extends Builder[A, Nothing] {
def +=(elem: A): this.type = this
def iterator: Iterator[A] = Iterator.empty
def result() = throw new UnsupportedOperationException("TraversableView.Builder.result")
def clear() {}
}
type Coll = TraversableView[_, C] forSome {type C <: Traversable[_]}
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, TraversableView[A, Traversable[_]]] =
new CanBuildFrom[Coll, A, TraversableView[A, Traversable[_]]] {
def apply(from: Coll) = new NoBuilder
def apply() = new NoBuilder
}
}
Run Code Online (Sandbox Code Playgroud)
TraversableView甚至这样的工作怎么样?似乎这里什么也没发生(NoBuilder似乎恰当地命名).
可能有人解释(1),该函数NoBuilder在这里踢球和(2)如何map,filter等等仍然可以正常工作?
的NoBuilder存在,使客户可以把Scala的意见,如果他们改造时他们正常的集合.它是一个虚拟实现,允许TraversableView扩展Traversable和调用方法,map而不知道集合是视图还是普通集合.
当你打电话map,flatMap或者scanLeft(称为变压器上的斯卡拉收集操作),一个CanBuildFrom隐含参数会自动解决.该CanBuildFrom对象是对象的抽象工厂Builder.
大多数Scala集合用于通过调用buidler Builders来添加元素+=并生成新集合result.例如,给定一个构建器对象b,map这样做:
def map[S, That](f: T => S)(implicit cbf: CanBuildFrom[Repr, S, That]) = {
val b: Builder[S, That] = cbf(this)
for (x <- this) b += f(x)
b.result
}
Run Code Online (Sandbox Code Playgroud)
视图上的Transformer操作不会实例化新集合.相反,他们创造了一个懒惰的视图.例如,map做这样的事情:
def map[S, That](f: T => S)(implicit cbf: CanBuildFrom[Repr, S, That]) = new TraversableView {
def foreach[U](forFunc: T => U): Unit = for (x <- self) forFunc(f(x))
}
Run Code Online (Sandbox Code Playgroud)
请注意,map在视图上具有相同的签名,但并没有真正调用+=和result对建设者.因此,NoBuilder视图中使用的并不真正需要存储元素或返回集合,它只是一个虚拟的方法永远不会被调用.
相同的签名允许在客户端代码中写入:
def foo(xs: Traversable[Int]) = xs.map(_ + 1)
foo(0 until 100)
foo((0 until 100).view)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
97 次 |
| 最近记录: |