scala – CanBuildFrom如何知道某个类型是否可以从另一个类型构
发布时间:2020-12-16 18:16:18 所属栏目:安全 来源:网络整理
导读:我读了 official doc,但我还是不明白它是如何工作的.例如: class A { type Self}def seqToSet[T : A](seq: Seq[T]) (implicit cbf: CanBuildFrom[Seq[T],T#Self,Set[T]]) {} 上面的代码可以编译……但是怎么样? Scala如何知道Set可以从Seq构建?怎么能确保
我读了
official doc,但我还是不明白它是如何工作的.例如:
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]? 解决方法
它一般不知道.你应该提供这样的CanBuildFrom.
对于像这样的简单情况,你可以使用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(elem)创建新的A2. 让我们用几乎相同的参数创建更有用的方法: def seqToSet[T <: A](seq: Seq[T])(f: T => T#Self) (implicit cbf: CanBuildFrom[Seq[T],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转换. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |