7

VectorBuilder在与 . 相同的源文件中定义VectorVector是不可变的并且在scala.collections.immutable包中,因此构建器在同一个包中。

据我所知,如果没有明确输入返回类型,则CanBuildFrom使用 a作为默认值。VectorBuilder

  • 是否有理由不将构建器放在可变包中的单独文件中?
  • 生成器不是要直接使用吗?如果是这样,将使用哪个构建器或缓冲区来创建Seq
4

2 回答 2

3

VectorBuilder不打算直接使用。如果您想获得 a 的构建器Vector,您只需要调用Vector.newBuilder[T],它会返回 a Builder[T, Vector[T]](底层实例是 a VectorBuilder)。

因此,如果您想要用于创建的默认构建器Seq,您只需调用Seq.newBuilder

scala> Seq(1,2,3)
res0: Seq[Int] = List(1, 2, 3)

scala> Seq.newBuilder[Int]
res1: scala.collection.mutable.Builder[Int,Seq[Int]] = ListBuffer()

scala> Seq.newBuilder[Int].result
res2: Seq[Int] = List()

上面显示了默认实现Seq是 list,从逻辑上讲,a 的默认构建器Seq实际上是 a mutable.ListBuffer

ListBuffer不仅仅是一个Listbuilder,这就是为什么它在collection.mutableVectorBuilderis not a的原因Buffer,它不能用于除了 build a 之外的任何其他东西Vector。这可能是它在本地定义的原因Vector。我不知道为什么不是private,我看不到它在其公共 API 的任何地方被引用Vector。也许它应该是(私人的)。


仅供参考,没有隐藏的魔法发生CanBuildFrom,它几乎总是通过newBuilder上面的:

  1. 当您没有指定预期的集合类型时,如在 中Seq(1,2).map(_+1),唯一可用CanBuildFrom 的来自伴随对象 a Seq,并且是 类型CanBuildFrom[Seq[_], T, Seq[T]]。这意味着结果也将是一个Seq

  2. 像大多数集合的伴随对象一样,该CanBuildFrom实例Seq只提供一件事:调用Seq.newBuilder(在GenTraversableFactory中定义......)

这就是为什么CanBuildFromforVector使用VectorBuilder. 例如,在这个:

scala> Vector(1,2,3).map(_+1)
res12: scala.collection.immutable.Vector[Int] = Vector(2, 3, 4)

使用的构建器是:

scala> implicitly[CanBuildFrom[Vector[Int], Int, Vector[Int]]].apply()
res13: scala.collection.mutable.Builder[Int,Vector[Int]] = 
  scala.collection.immutable.VectorBuilder@43efdf93
于 2013-07-11T20:12:00.700 回答
1

没有可变向量。与 类比ListSetBuilder,建造者离它正在建造的东西很近。

mutable.StringBuilder是异常的,因为它是一个经常使用的类型,并且更一流,并且倾向于通过 API 传递。(它在集合概述中被提及,不需要导入。事实上,它在这个谜题中发挥了作用,因为它与 Java 有细微的不同,StringBuilder但你可能会忘记你正在使用它。)

VectorBuilder是公共 API。newBuilderon 伴随对象与集合工厂框架和CanBuildFrom. 在解释如何制作东西的概述中也没有提到。我不记得有任何建议的片段:

(ListBuffer.newBuilder[String] += "hello" += "world").result.toList

您如何创建 aVector取决于您在做什么,但概述建议使用配套的工厂方法。如果您已经有一个集合(可能是非严格的),那么toVector. 你如何收集任何东西?

这是关于为您的 Seq 选择 V​​ector over List 的一个很好的问答。

作为实现细节,VectorPointer您在 scaladoc 中看到的内容包括一个重要注释:

// USED BY BUILDER

既然VectorPointerprivate[immutable],建设者必须留在那里作为一个实际的问题。这也表明人们对将哪些内容作为 API 公开给出了一些想法。

此外,Vector还有类似的评论:

// in principle, most members should be private. however, access privileges must
// be carefully chosen to not prevent method inlining

这些评论表明访问级别不是随意的。

这个问题是一个思考包装设计的有趣机会。可能 Scala 的收藏品是罗夏墨迹测验,揭示了伟大的美感和对称性,同时,对于心烦意乱的人来说,宇宙中的巨大不平衡。(有点开玩笑。)

于 2013-07-12T06:00:41.047 回答