【问题标题】:Generic type parser in scala 2.10Scala 2.10 中的通用类型解析器
【发布时间】:2013-12-21 17:39: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")
  }
}

但这似乎很冗长和复杂,所以我想知道有没有更简单的方法可以做到这一点?

【问题讨论】:

    标签: scala generics


    【解决方案1】:

    将运行时错误用于编译时条件似乎很奇怪。你考虑过类型类吗?

    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)
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-05
        • 1970-01-01
        • 2012-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多