あなたのJsonParser.parse
を動作させる方法はScalaでは不可能です。 Scalaは強く静的に型付けされた言語です。これは、コンパイラがコンパイル時に値の型を知っていることを確認して、有効なフィールドとメソッドのみにアクセスし、有効なパラメータとしてメソッドに渡すことを検証できることを意味します。あなたのクラスを想定し
case class Entity1(value:Int, unique1:Int)
case class Entity2(value:String, unique2:String)
であり、あなたはコンパイラがparsed.value
の種類を知っているかparsed.unique2
がない間parsed.unique1
が有効なフィールドであることを知ることがparsed
の種類を知ることができる方法
val parsed = JsonParser.parse[mapping("entity1")](jsonString)
を書くのか?最適な型のコンパイラがparsed
に割り当てることができるのは、Any
のような非常に一般的なものです。もちろん、Any
を特定のタイプにダウンキャストすることができますが、これはどんな種類の目的を果たしているのかをasInstanceOf
で明示的に指定しなければならないことを意味します。
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))
}
をしてから、このような何か::それでも、何とかAny
を返すことはあなたのためにOKであれば、あなたはこのような何かをしようとするかもしれ
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")
}
P.S.をentityName
が外部から来ていない場合(つまり、実際のタイプを見つけるためにデータを分析しない場合)、実際にはそれを必要としません。アンモナイトREPLに貼り付けるためのスニペットとして、@SergGrからアイデア後
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")
}
...実行時のものとコンパイル時のものを混在させています。 –