我在Scala上尝试了CanBuildFrom trait,当我尝试自动将Array类型转换为Seq类型时它看起来很好,我认为原因是我们在范围内有CanBuildFrom [Array,T,Seq [T]]。但是,如果我尝试将Array转换为Set,则无法正常工作。此外,将Seq转换为Set也不起作用。我只是想知道我是否应该将相同类型的CanBuildFrom隐式定义为同伴对象来实现转换?如果是,为什么scala默认不提供它,原因是Set是一个函数吗?
以下是Array to Seq
的代码def transform[U[_]](col: Array[String])(implicit cbf: CanBuildFrom[Array[String], String, U[String]]): U[String] = {
val builder = cbf()
for (ele <- col) builder += ele
builder.result()
}
CanBuildFromSpec.transform[Seq](Array("123", "3"))
如果我想转换为Array to Set或List,则无法正常工作
CanBuildFromSpec.transform[List](Array("123", "3")) //compilation error, cannot construct
CanBuildFromSpec.transform[Set](Array("123", "3")) //compilation error, cannot construct
答案 0 :(得分:3)
无需重新发明轮子 - Scala集合具有to[C[_]]
方法,可以根据需要进行转换:
scala> List(1, 2, 3).to[Vector]
res0: Vector[Int] = Vector(1, 2, 3)
scala> Array(1, 2, 3).to[Seq]
res1: Seq[Int] = Vector(1, 2, 3)
scala> Seq(1, 2, 3).to[Set]
res2: Set[Int] = Set(1, 2, 3)
BTW,引入CanBuildFrom
并非易于转换。需要这样才能使map()
或filter()
等操作保留原始集合类型。
同样Array
自动转换为Seq
因为CanBuildFrom
(这意味着数组内容被复制到新序列中,这可能效率很低),但因为那里是从数组到其包装器的隐式转换,提供Seq
接口。