CanBuildFrom 如何知道一个类型是否可以从另一个类型构建? [英] How does CanBuildFrom know whether a type can build from another?
问题描述
我阅读了官方文档我仍然无法理解它是如何工作的.例如:
I read the official doc but I can't still understand how it works. For example:
class A {
type Self
}
def seqToSet[T <: A](seq: Seq[T])
(implicit cbf: CanBuildFrom[Seq[T], T#Self, Set[T]]) {}
上面的代码可以编译……但是怎么编译呢?Scala 如何知道 Set
可以从 Seq
构建?以及如何确保 T#Self
(实际上是任何类型)可以放入 Set[T]
中?
The above code can be compiled... but how? How does Scala know a Set
can be built from a Seq
? And how could it ensure a T#Self
(literally any type) can be put into Set[T]
?
推荐答案
一般不知道.你应该提供这样的CanBuildFrom
.
It don't know it in general. You should provide such CanBuildFrom
.
对于像这样的简单情况,您可以使用 breakOut
:
For simple cases like this you could use breakOut
:
class A1 extends A { type Self = A1 }
seqToSet(new A1 :: Nil)(collection.breakOut)
// compiles fine
对于更复杂的情况:
case class A2(val i: Int) extends A {
type Self = Int
}
implicit val A2cbf = new CanBuildFrom[Seq[A2],A2#Self,Set[A2]] {
import scala.collection.mutable.Builder
class A2Builder extends Builder[A2#Self,Set[A2]] {
var es = List[A2]()
def +=(elem: A2#Self): this.type = { es ::= A2(elem); this }
def clear(): Unit = es = Nil
def result(): Set[A2] = es.toSet
}
def apply() = new A2Builder
def apply(from: Seq[A2]) = apply()
}
seqToSet(new A2 :: Nil)(collection.breakOut)
// compiles fine
您应该提供 Builder
(使用 CanBuildFrom
),以便它在方法 +=
中接受 A2#Self
并返回 Set[A2]
作为结果.在代码示例中,它使用 elem
创建新的 A2
:A2(elem)
.
You should provide Builder
(using CanBuildFrom
) such that it accepts A2#Self
in method +=
and returns Set[A2]
as result. In code sample it creates new A2
using elem
: A2(elem)
.
让我们用几乎相同的参数创建更有用的方法:
Let's create more useful method with almost the same parameters:
def seqToSet[T <: A](seq: Seq[T])(f: T => T#Self)
(implicit cbf: CanBuildFrom[Seq[T], T#Self, Set[T]]) = {
seq.map{f}: Set[T]
}
seqToSet(A2(1) :: A2(2) :: Nil){ a2 => a2.i + 1 }
// Set[A2] = Set(A2(3), A2(2))
这个方法提供了一些奇怪的A
转换和集合类型转换.
This method provides some strange transformation of A
with transformation of collection type.
这篇关于CanBuildFrom 如何知道一个类型是否可以从另一个类型构建?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!