scala将String转换为泛型类型

时间:2013-07-18 12:06:42

标签: scala

我正在解析一个json。我想将它的值转换为其他类型。 即

//json = JSON String 
val seq = net.liftweb.json.parse(json).\\("seq").values.toString.toLong
val userName = net.liftweb.json.parse(json).\\("name").values.toString
val intNum = net.liftweb.json.parse(json).\\("intId").values.toInt

我想用通用方法更加“scala”方式来投射它,我试过这样的事情:

object Converter{
  def JSONCaster[T](json:String,s:String):T={
    net.liftweb.json.parse(json).\\(s).values.toString.asInstanceOf[T]
  }
}

但是出现了投射错误:

  

java.lang.ClassCastException:java.lang.String无法强制转换为   java.lang.Long at scala.runtime.BoxesRunTime.unboxToLong(未知   源)

4 个答案:

答案 0 :(得分:3)

我遇到了同样的问题,并记得Play框架有一些功能可以做类似的事情。在挖掘源代码后,我发现了这个Class

基本上,我们可以这样做:

object JSONCaster {

  def fromJson[T](json: String, s: String)(implicit converter: Converter[T]): T = {
    converter.convert(net.liftweb.json.parse(json).\\(s).values.toString)
  }

  trait Converter[T] { self =>
    def convert(v: String): T
  }

  object Converter{
    implicit val longLoader: Converter[Long] = new Converter[Long] {
      def convert(v: String): Long = v.toLong
    }

    implicit val stringLoader: Converter[String] = new Converter[String] {
      def convert(v: String): String = v
    }

    implicit val intLoader: Converter[Int] = new Converter[Int] {
      def convert(v: String): Long = v.toInt
    }

    // Add any other types you want to convert to, even custom types!
  }
}

可以像:

一样调用
JSONCaster.fromJson[Long](json, "seq")

缺点是我们必须为我们想要转换的所有类型定义隐式转换器。这样做的好处是使界面非常干净和可重复使用。

答案 1 :(得分:1)

看一下在Spray中实现的marshalling/unmarshalling。您可能不需要重新发明解决方案,如果这样做,您可以查看their source以了解它们是如何实现的。

Spray的编组/解组类似于对象图序列化,并且不仅仅使用JSON,因此在实现中还有一些额外的固有复杂性。

您也可以手动解析JSON并尝试lift-json

lift-json更接近JSON虽然通过extract它可以像Spray的marshaller / unmarshaller那样操作。

答案 2 :(得分:0)

我找到的最佳和最好的解决方案是Derek Wyatt's Blog -heres one of the reasons why monads are awesome

答案 3 :(得分:0)

在这里,我在scala中有一个通用方法,可以使用liftweb / lift-json。 作为一个主意,您需要提供隐式清单。

import net.liftweb

private def jsonToObjectsSeq[T](jsonAsString: String)(implicit man: Manifest[T]): Seq[T] = {
  parse(jsonAsString)
    .children
    .map(_.extract[T])
}