2013-12-21 24 views
3

我正在使用Scala 2.10编写一个通用值解析器。 输入是一个字符串,输出是用户给出的通用类型。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") 
    } 
} 

但似乎非常繁琐和复杂,所以我不知道有没有什么简单的方法来做到这一点?

回答

8

在编译时条件下使用运行时错误似乎很奇怪。你有没有考虑过类型班?

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) 
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 ??? 
}