我有一个泛型方法,它应该返回与输入类型相同的集合:
def removeN[A, C <: Seq[A]](s: C, n: Int): C = {
s.take(n) ++ s.drop(n + 1) // Sample operation
}
但是这段代码没有编译:
错误:(34,15)类型错配;发现: SeqA必需:C s.take(n) ++ s.drop(n + 1)
C
明确表示Seq[A]
,这怎么可能?这是否意味着这种连接总是返回父类型Seq[A]
的实例,而不是子类型C
?可以重写我的代码以生成一个类型为C
的集合吗?Seq
的子类型)?Scala 2.12.4
发布于 2017-11-16 02:00:28
您所要求的可以使用集合库中最强大但最具争议的特性之一,即CanBuildFrom
来完成。以下是如何:
import scala.language.higherKinds
import scala.collection.generic.CanBuildFrom
def removeN[A, C[A] <: Seq[A]](s: C[A], n: Int)
(implicit cbf: CanBuildFrom[C[A], A, C[A]]): C[A] = {
val builder = cbf()
builder.sizeHint(s.size)
builder ++= s.take(n)
builder ++= s.drop(n + 1)
builder.result()
}
让我们在REPL中做一个转折:
scala> removeN(List(4, 5, 6), 2)
res0: List[Int] = List(4, 5)
scala> removeN(Vector(4, 5, 6), 2)
res1: scala.collection.immutable.Vector[Int] = Vector(4, 5)
好像很管用。
为了避免对更高类型(CA)的使用发出警告,需要使用import scala.language.higherKinds
。
https://stackoverflow.com/questions/47325295
复制相似问题