我正在使用Scala 2.10编写通用值解析器。 输入是一个字符串,输出是泛型类型,由用户给出。
我唯一能想到的是
val StringTYPE = classOf[java.lang.String]
def parseValue[T: ClassTag](str: String): T = {
implicitly[ClassTag[T]].runtimeClass match {
case java.lang.Integer.TYPE => str.toInt.asInstanceOf[T]
case java.lang.Long.TYPE => str.toLong.asInstanceOf[T]
case StringTYPE => str.asInstanceOf[T]
case _ => throw new Exception("Unknown type")
}
}
但它看起来非常冗长和复杂,所以我想知道有更简单的方法吗?
答案 0 :(得分:9)
在编译时条件中使用运行时错误似乎很奇怪。你考虑过类型课吗?
trait Readable[T] {
def read(str: String): T
}
object Readable {
implicit object IntIsReadable extends Readable[Int] {
def read(str: String): Int = str.toInt
}
// ... provide similar objects for any types that can be "read" ...
// if possible, inside object Readable
// or inside the companion object of the type you want to make readable.
// Otherwise, ensure that the implicit is in scope when calling Read
}
def readValue[T: Readable](str: String): T = implicitly[Readable[T]].read(str)
答案 1 :(得分:0)
解决方案由Aaron提供,正确的方法是类型类。
只是建议对您的版本进行微小改进(但不要这样做),您可以直接使用ClassTag进行检查。另外,命名隐式参数可能比隐式返回更容易:
def parseValue[T](str: String)(implicit tag: ClassTag[T]): T = {
if(tag == ClassTag.Int) str.toInt.asInstanceOf[T]
else if(tag == ClassTag.Long) ...
else if (tag == ClassTag(classOf[String]) …
else ???
}