您希望 JsonParser.parse 工作的方式在 Scala 中是不可能的。 Scala 是一种强类型和静态类型的语言。这意味着编译器应该在编译时知道值的类型,以便能够验证您仅访问它们上的有效字段和方法和/或将它们作为有效参数传递给方法。假设你的课程是
case class Entity1(value:Int, unique1:Int)
case class Entity2(value:String, unique2:String)
然后你写
val parsed = JsonParser.parse[mapping("entity1")](jsonString)
编译器如何知道parsed 的类型以知道parsed.value 的类型或知道parsed.unique1 是有效字段而parsed.unique2 不是?可以分配给此类parsed 的最佳类型编译器是非常通用的,例如Any。当然,您可以稍后将 Any 向下转换为特定类型,但这意味着您仍然必须在 asInstanceOf 中明确指定该类型,这会破坏整个目的。不过,如果以某种方式返回 Any 对您来说是可以的,您可以尝试执行以下操作:
import org.json4s.jackson.JsonMethods
implicit val formats = org.json4s.DefaultFormats // or whatever Formats you actually need
val typeMap: Map[String, scala.reflect.Manifest[_]] = Map(
"String" -> implicitly[scala.reflect.Manifest[String]],
"Int" -> implicitly[scala.reflect.Manifest[Int]]
)
def parseAny(typeName: String, jsonString: String): Any = {
val jValue = JsonMethods.parse(jsonString)
jValue.extract(formats, typeMap(typeName))
}
然后做这样的事情:
def testParseByTypeName(typeName: String, jsonString: String): Unit = {
try {
val parsed = parseAny(typeName, jsonString)
println(s"parsed by name $typeName => ${parsed.getClass} - '$parsed'")
} catch {
case e => println(e)
}
}
def test() = {
testParseByTypeName("String", "\"abc\"")
testParseByTypeName("Int", "123")
}
附:如果您的 entityName 不是来自外部(即您不分析数据以找出实际类型),那么您实际上根本不需要它。使用类型就足够了(不需要match/case)例如:
def parse[T](jsonString: String)(implicit mf: scala.reflect.Manifest[T]): T = {
val jValue = JsonMethods.parse(jsonString)
jValue.extract[T]
}
def testParse[T](prefix: String, jsonString: String)(implicit mf: scala.reflect.Manifest[T]): Unit = {
try {
val parsed = parse[T](jsonString)
println(s"$prefix => ${parsed.getClass} - '$parsed'")
} catch {
case e => println(e)
}
}
def test() = {
testParse[String]("parse String", "\"abc\"")
testParse[Int]("parse Int", "123")
}