3

Scala プロジェクトで JSON をシリアライズ/デシリアライズするためにArgonaut ( http://argonaut.io ) をラップしようとしています。以前はJerksonを使用していましたが、廃止されたため、代替品を探しています.

これは基本的な JSON ラッパーです

import argonaut._, Argonaut._

object Json {
  def Parse[T](input: String): T = {
    input.decodeOption[T].get
  }
}

これをコンパイルしようとすると、次のエラーが発生します。

could not find implicit value for evidence parameter of type argonaut.DecodeJson[T]
    input.decodeOption[T]
                  ^
not enough arguments for method decodeOption: (implicit evidence$6: argonaut.DecodeJson[T]) Option[T].
Unspecified value parameter evidence$6.
    input.decodeOption[T]
                  ^

これを修正する方法についての提案や、私が間違っていることについての指針をいただければ幸いです。

また、代替の JSON フレームワークに関する提案も大歓迎です。

私は Scala/Java とそこでジェネリックがどのように機能するかは初めてですが、.NET/C# を何年も書いています。

4

2 に答える 2

7

コードを機能させるには、次のJsonようにオブジェクトを再定義する必要があります。

object Json {
  def Parse[T](input: String)(implicit decode:DecodeJson[T]): Option[T] = {
    input.decodeOption[T]
  }
}

あなたが見逃していたのは、関数がデコード方法を理解するために必要な暗黙のDecodeJsonインスタンスでした。decodeOptionまた、戻り値の型Option[T]を単に ではなくas として定義する必要がありますT。このすべてが機能する完全な例は、次のようになります。

import argonaut._, Argonaut._
case class User(id:Long, email:String, name:String)

object Json {
  def Parse[T](input: String)(implicit decode:DecodeJson[T]): Option[T] = {
    input.decodeOption[T]
  }
}

object JsonTest{
  implicit val userDecode = casecodec3(User.apply, User.unapply)("id", "email", "name")

  def main(args: Array[String]) {
    val json = """{
      "id": 1,
      "email": "foo@test.com",
      "name": "foo bar"
    }"""

    val userOpt = Json.Parse[User](json)
    println(userOpt)
  }
}

他の Json フレームワークに関しては、以下を調べることができます。

Jsonを再生

json4s

スプレー-json

Jackson Scala モジュール

于 2013-06-11T12:08:50.817 に答える
4

ほとんどすべての scala シリアライゼーション ライブラリと同様に、Argonaut は型クラス パターンを使用しているようです。これは派手なことのように聞こえますが、実際には、 type のオブジェクトをシリアル化/逆シリアル化するときTに、プロセスの一部またはすべてが延期される別のオブジェクトのインスタンスを暗黙的に渡す必要があることを意味します。具体的には、 をdecodeOption[T]実行する場合、スコープ内に のインスタンスが必要ですargonaut.DecodeJson[T](decodeOptionデシリアライズ中に使用されます)。

あなたがしなければならないことは、単にこの暗黙の値を に渡すことを要求することですParse(その後、自動的に に渡されdecodeOptionます:

def Parse[T](input: String)(implicit decoder: argonaut.DecodeJson[T]): Option[T] = {
  input.decodeOption[T]
}

Scala には、宣言を短くするためのシンタックス シュガーも用意されています (これは「コンテキスト バインド」と呼ばれます)。

def Parse[T:argonaut.DecodeJson](input: String): Option[T] = {
  input.decodeOption[T]
}

ここで、 を呼び出すときにParse、 の暗黙的な値をスコープに取り込む必要があります。そうargonaut.DecodeJsonしないと、呼び出しがコンパイルに失敗します。どうやら、Argonautオブジェクトは既に多くの標準型のデコーダーを定義しているようです。そのため、それらの型に対して特別なことをする必要はありません。他のタイプ (独自のカスタム タイプなど) については、デコーダーを定義してインポートする必要があります。

于 2013-06-11T12:07:31.520 に答える