gpt4 book ai didi

scala - scala.collection.TraversableView.NoBuilder 是如何工作的?

转载 作者:行者123 更新时间:2023-12-04 15:11:05 26 4
gpt4 key购买 nike

我读了

  • Architecture of Scala Collections
  • How are Scala collections able to return the correct collection type from a map operation?
  • 当然,Is the Scala 2.8 collections library a case of "the longest suicide note in history"?

  • 我想我对 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
    }
    }
    TraversableView如何甚至像这样工作?似乎这里没有发生任何事情( NoBuilder 似乎恰本地命名)。

    有人可以解释(1) NoBuilder 的功能吗?在这里播放和(2)如何 map , filter等还能工作吗?

    最佳答案

    NoBuilder存在以便客户在转换它们时可以将 Scala View 视为普通集合。它是一个虚拟实现,允许 TraversableView延长 Traversable并调用像 map 这样的方法不知道该集合是 View 还是普通集合。

    更长的解释

    当您调用 map , flatMapscanLeft (称为转换器操作)在 Scala 集合上,CanBuildFrom隐式参数会自动解析。 CanBuildFrom object 是 Builder 的抽象工厂对象。

    大多数 Scala 集合使用 Builders使用 += 添加元素并通过调用 result 生成一个新集合在 builder 上。例如。给定一个构建器对象 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
    }

    View 上的转换器操作不会实例化新集合。相反,他们创建了一个惰性 View 。例如, 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))
    }

    请注意, map on a view 具有相同的签名,但并不真正调用 +=result在生成器上。因此, NoBuilder在 View 中使用并不真正需要存储元素或返回集合,它只是一个永远不会调用其方法的虚拟对象。

    相同的签名允许在客户端代码中编写:
    def foo(xs: Traversable[Int]) = xs.map(_ + 1)
    foo(0 until 100)
    foo((0 until 100).view)

    关于scala - scala.collection.TraversableView.NoBuilder 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24462742/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com