我想定义一种压缩方法,将特定类型Int
或String
的集合压缩为字符串。我想结合我目前拥有的两种方法:
def compressString[T <: IndexedSeq[String]]: (T) =>
String = (array: T) => array.mkString(" ")
def compressInt[T <: IndexedSeq[Int]]: (T) =>
String = (array: T) => array.mkString(" ")
进入一个方法。我尝试使用T[Int]
做更高级的kinded类型,但它没有那样工作。我也尝试过:
def compress[U, T <: IndexedSeq[U]]: (T) => String =
(array: T) => array.mkString(" ")
然而,编译器给了我这个错误:
[error] type mismatch;
[error] found : Iterator[Int(in method compress)]
[error] required: Iterator[scala.Int]
[error] collect(array.iterator, Vector.empty[String], 0).mkString("\t")
[error] ^
[error] SVM.scala:55: type mismatch;
[error] found : java.lang.String
[error] required: String(in method compress)
[error] override def compress[String, T <: IndexedSeq[String]]: (T) => String = (array: T) => array.mkString("\t")
通常,我希望最终覆盖此方法并提供具体实现(处理Int
的方法与String
不同)。我如何结合这两种方法??
答案 0 :(得分:8)
为了使你的泛型方法编译,你需要传递第一个类型的参数作为IndexedSeq的类型,即
def compress[U, T <: IndexedSeq[U]]: (T) => String = {
(array: T) => array.mkString(" ")
}
then you can invoke it like,
val strings = compress[String,Vector[String]](Vector("a","b")) // strings: String = a b
val ints = compress[Int,Vector[Int]](Vector(1,2)) // ints: String = 1 2
但是,我认为type class在您希望具有ad hoc多态性的情况下更适合。
例如,您可以定义以下类型类:
@implicitNotFound("No compressor found for type ${T}")
trait Compressor[T] {
def compress(array: IndexedSeq[T]): String
}
并为要支持压缩的每种类型创建一个实现
implicit val stringCompressor = new Compressor[String] {
override def compress(array: IndexedSeq[String]): String = array.mkString(" ")
}
implicit val intCompressor = new Compressor[Int] {
override def compress(array: IndexedSeq[Int]): String = array.mkString(" ")
}
然后你可以直接调用方法
val strings = stringCompressor.compress(Vector("a","b")) // strings: String = a b
val ints = intCompressor.compress(Vector(1,2)) // ints: String = 1 2
或者您可以定义采用隐式参数
的通用方法def compress[T](array: IndexedSeq[T])(implicit compressor: Compressor[T]): String = {
compressor.compress(array)
}
// or equivalently
def compress[T: Compressor](array: IndexedSeq[T]): String = {
implicitly[Compressor[T]].compress(array)
}
并像这样使用
val strings = compress(Vector("a","b")) // strings: String = a b
val ints = compress(Vector(1,2)) // ints: String = 1 2
如果范围中没有定义隐式压缩器,编译器会给出错误,例如
compress(Vector(true, false))
error: No compressor found for type Boolean
compress(Vector(true, false))
^
希望它有所帮助。