我有一个模板化的类,根据T的类型,我想打印不同的东西。
class Clazz[T](fn: T => String) {}
理想情况下,我想做模式匹配T(我不能这样做):
T match {
case x:Int => println("function from int to string")
case _ => //... and so forth
}
我试过了:
class Clazz[T](fn: T => String) {
def resolve():String = fn match {
case f:(Int => String) => println("function from int to string")
case _ => //...etc.
}
}
我得到的错误信息是:
non-variable type argument Int in type pattern Int => String is unchecked since it is eliminated by erasure
有办法解决这个问题吗?
答案 0 :(得分:4)
我会使用TypeTag
,因此我可以将T
与其他类型进行比较而不会丢失任何类型信息:
import scala.reflect.runtime.universe._
class Clazz[T: TypeTag](fn: T => String) {
val resolve = typeOf[T] match {
case t if t =:= typeOf[Int] => "function from Int to String"
case t if t =:= typeOf[Byte] => ..
}
}
但如果我只想打印出与toString
不同的内容,我会使用类型类:
trait Print[T] {
def toText(t: T): String
def apply(t: T) = print(toText(t))
}
def print[T: Print](t: T) = implicitly[Print[T]].apply(t)
implicit object PrintInt extends Print[Int] {
def toText(t: Int) = s"Int: $t"
}
implicit object PrintByte extends Print[Byte] {
def toText(t: Byte) = s"Byte: $t"
}
PrintInt(3) //=> Int: 3
print(3) //=> Int: 3
如果你添加它, 3.print
甚至可以:
implicit class Printable[T:Print](t: T) {
def print = implicitly[Print[T]].apply(t)
}
3.print //=> Int: 3