標準の Scala ライブラリでの JSON サポートは、おそらく最良の選択ではありません。残念ながら、Scala の JSON ライブラリの状況は少し混乱しています。多くの代替手段(Lift JSON、Play JSON、Spray JSON、Twitter JSON、Argonaut など) があり、基本的に曜日ごとに 1 つのライブラリがあります...少なくともこれらを見て、使いやすく、パフォーマンスが高いものがあるかどうかを確認することをお勧めします。
これは、特定の理由 (マクロでフォーマットを生成できる) で選択した Play JSON を使用した例です。
object JsonTest extends App {
import play.api.libs.json._
type MyDict = Map[String, Int]
implicit object MyDictFormat extends Format[MyDict] {
def reads(json: JsValue): JsResult[MyDict] = json match {
case JsObject(fields) =>
val b = Map.newBuilder[String, Int]
fields.foreach {
case (k, JsNumber(v)) => b += k -> v.toInt
case other => return JsError(s"Not a (string, number) pair: $other")
}
JsSuccess(b.result())
case _ => JsError(s"Not an object: $json")
}
def writes(m: MyDict): JsValue = {
val fields: Seq[(String, JsValue)] = m.map {
case (k, v) => k -> JsNumber(v)
} (collection.breakOut)
JsObject(fields)
}
}
val m = Map("hallo" -> 12, "gallo" -> 34)
val serial = Json.toJson(m)
val text = Json.stringify(serial)
println(text)
val back = Json.fromJson[MyDict](serial)
assert(back == JsSuccess(m), s"Failed: $back")
}
直接構築および分解できますがJsValues
、主なアイデアは、データ構造の型であるFormat[A]
whereを使用することです。A
これにより、標準の Scala-Library JSON よりもタイプ セーフが強調されます。より冗長に見えますが、最終的にはそれがより良いアプローチだと思います。
必要な型の暗黙的な形式を探すユーティリティ メソッドがありJson.toJson
ます。Json.fromJson
一方、すべてをメモリ内に構築し、データ構造を複製します (マップ内のエントリごとに別の tuple が(String, JsValue)
あるため)。 GBの大きさで動作しています...
Jerkson は、Java JSON ライブラリ Jackson の Scala ラッパーです。後者には明らかにデータをストリーミングする機能があります。ストリーミングサポートを追加するというこのプロジェクトを見つけました。Play JSON は Jerkson に基づいているため、おそらくそれを使用してオブジェクトをストリーミングする方法を理解することさえできます。この質問も参照してください。