Scala - 解析模板类型

时间:2014-07-19 19:24:19

标签: scala

我有一个模板化的类,根据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

有办法解决这个问题吗?

1 个答案:

答案 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