有没有办法用泛型来概括这段代码?
object ListInt {
def unapply(o: Any): Option[List[Int]] = o match {
case lst: List[_] if(lst.forall(_.isInstanceOf[Int])) =>
Some(lst.asInstanceOf[List[Int]])
case _ => None
}
}
object ListDouble {
def unapply(o: Any): Option[List[Double]] = o match {
case lst: List[_] if(lst.forall(_.isInstanceOf[Double])) =>
Some(lst.asInstanceOf[List[Double]])
case _ => None
}
}
object ListString {
def unapply(o: Any): Option[List[String]] = o match {
case lst: List[_] if(lst.forall(_.isInstanceOf[String])) =>
Some(lst.asInstanceOf[List[String]])
case _ => None
}
}
val o: Any = List("a", "b", "c")
o match {
case ListInt(lst) => println(lst.sum)
case ListDouble(lst) => println(lst.product)
case ListString(lst) => println(lst.mkString("(", ", ", ")"))
case _ => println("no match")
}
答案 0 :(得分:6)
abstract class ListExtractor[A](implicit ct: reflect.ClassTag[A]) {
def unapply(o: Any): Option[List[A]] = o match {
case lst: List[_] if (lst.forall(ct.unapply(_).isDefined)) =>
Some(lst.asInstanceOf[List[A]])
case _ => None
}
}
object ListInt extends ListExtractor[Int ]
object ListString extends ListExtractor[String]
val o: Any = List("a", "b", "c")
o match {
case ListInt (lst) => println(lst.sum)
case ListString(lst) => println(lst.mkString("(", ", ", ")"))
case _ => println("no match")
}
答案 1 :(得分:3)
似乎TypeTag是要走的路:
import scala.reflect.runtime.universe._
def foo[A: TypeTag](lst: A) = typeOf[A] match {
case t if t =:= typeOf[List[Int]] => lst.asInstanceOf[List[Int]].sum
case t if t =:= typeOf[List[Double]] => lst.asInstanceOf[List[Double]].product
case t if t =:= typeOf[List[String]] => lst.asInstanceOf[List[String]].mkString("(", ", ", ")")
}
println(foo(List("a", "b", "c")))
查看这篇优秀文章,了解详细说明: