VectorBuilder
在与 . 相同的源文件中定义Vector
。Vector
是不可变的并且在scala.collections.immutable包中,因此构建器在同一个包中。
据我所知,如果没有明确输入返回类型,则CanBuildFrom
使用 a作为默认值。VectorBuilder
- 是否有理由不将构建器放在可变包中的单独文件中?
- 生成器不是要直接使用吗?如果是这样,将使用哪个构建器或缓冲区来创建
Seq
?
VectorBuilder
在与 . 相同的源文件中定义Vector
。Vector
是不可变的并且在scala.collections.immutable包中,因此构建器在同一个包中。
据我所知,如果没有明确输入返回类型,则CanBuildFrom
使用 a作为默认值。VectorBuilder
Seq
?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
不仅仅是一个List
builder,这就是为什么它在collection.mutable
而VectorBuilder
is not a的原因Buffer
,它不能用于除了 build a 之外的任何其他东西Vector
。这可能是它在本地定义的原因Vector
。我不知道为什么不是private
,我看不到它在其公共 API 的任何地方被引用Vector
。也许它应该是(私人的)。
仅供参考,没有隐藏的魔法发生CanBuildFrom
,它几乎总是通过newBuilder
上面的:
当您没有指定预期的集合类型时,如在 中Seq(1,2).map(_+1)
,唯一可用CanBuildFrom
的来自伴随对象 a Seq
,并且是 类型CanBuildFrom[Seq[_], T, Seq[T]]
。这意味着结果也将是一个Seq
。
像大多数集合的伴随对象一样,该CanBuildFrom
实例Seq
只提供一件事:调用Seq.newBuilder
(在GenTraversableFactory中定义......)
这就是为什么CanBuildFrom
forVector
使用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
没有可变向量。与 类比ListSetBuilder
,建造者离它正在建造的东西很近。
mutable.StringBuilder
是异常的,因为它是一个经常使用的类型,并且更一流,并且倾向于通过 API 传递。(它在集合概述中被提及,不需要导入。事实上,它在这个谜题中发挥了作用,因为它与 Java 有细微的不同,StringBuilder
但你可能会忘记你正在使用它。)
VectorBuilder
是公共 API。newBuilder
on 伴随对象与集合工厂框架和CanBuildFrom
. 在解释如何制作东西的概述中也没有提到。我不记得有任何建议的片段:
(ListBuffer.newBuilder[String] += "hello" += "world").result.toList
您如何创建 aVector
取决于您在做什么,但概述建议使用配套的工厂方法。如果您已经有一个集合(可能是非严格的),那么toVector
. 你如何收集任何东西?
这是关于为您的 Seq 选择 Vector over List 的一个很好的问答。
作为实现细节,VectorPointer
您在 scaladoc 中看到的内容包括一个重要注释:
// USED BY BUILDER
既然VectorPointer
是private[immutable]
,建设者必须留在那里作为一个实际的问题。这也表明人们对将哪些内容作为 API 公开给出了一些想法。
此外,Vector
还有类似的评论:
// in principle, most members should be private. however, access privileges must
// be carefully chosen to not prevent method inlining
这些评论表明访问级别不是随意的。
这个问题是一个思考包装设计的有趣机会。可能 Scala 的收藏品是罗夏墨迹测验,揭示了伟大的美感和对称性,同时,对于心烦意乱的人来说,宇宙中的巨大不平衡。(有点开玩笑。)