2

私は自分のコードに暗黙的なパラメーターを持ち込むのが好きではないので、それらを使用する場所でそれらの使用をカプセル化したいと考えています。そのため、spray-json への呼び出しを例外処理でラップし、モデル クラスごとにデフォルトの暗黙的な JsonFormats を含むオブジェクトを定義しようとしています。ただし、暗黙的なパラメーターは、コードを呼び出すクライアントにインポートされない限り解決されません。これは、まさに私が望んでいない場所です。これが私がこれまでに持っているものです(暗黙のフォーマッタを解決しません)。私がやりたいことを得る方法はありますか?

package com.rsslldnphy.json

import com.rsslldnphy.models._
import spray.json._

object Json extends DefaultJsonProtocol {

  implicit val personFormat = jsonFormat1(Person)
  implicit val animalFormat = jsonFormat1(Animal)

  def parse[T](s:String)(implicit reader: JsonReader[T]): Option[T] = {
    try { Some(JsonParser(s).convertTo[T]) }
    catch { case e: DeserializationException => None }
  }
}

注意。JsonFormat は JsonReader の型です

編集:@paradigmaticの2番目の提案に基づいて私が書いたものは次のとおりです(これは機能しませんが、まだ取得できませんCannot find JsonReader or JsonFormat type class for T)。何か不足していますか?

object Protocols extends DefaultJsonProtocol {
  implicit val personFormat = jsonFormat1(Person)
  implicit val animalFormat = jsonFormat1(Animal)
}

object Json {

  def parse[T](s:String): Option[T] = {
    import Protocols._
    try { Some(JsonParser(s).convertTo[T]) }
    catch { case e: DeserializationException => None }
  }
}

記録として、これは機能するコード スニペットですが、あまりにも多くのクライアント コードを必要とするため (つまり、スコープ内に暗黙的なコードを含める必要があるため)、回避しようとしています。

object Json extends DefaultJsonProtocol {
  implicit val personFormat = jsonFormat1(Person)
  implicit val animalFormat = jsonFormat1(Animal)
}

object ClientCode {
  import Json._
  def person(s: String): Person = JsonParser(s).convertTo[Person]
}
4

1 に答える 1

7

コンパニオン オブジェクトで暗黙を宣言できます。

object Person {
  implicit val personFormat: JReader[Person] = jsonFormat1(Person)
}
object Animal {
  implicit val animalFormat: JReader[Animal] = jsonFormat1(Animal)
}

暗黙の解決ルールは非常に複雑です。詳細については、このブログ投稿を参照してください。しかし、コンパイラが typeclass を探している場合、T[A](遅かれ早かれ) class/trait のコンパニオン オブジェクトでそれを探しますA

編集:問題がスコープ「汚染」の問題のみである場合は、いくつかのブレースを導入できます。コード例では、関数 parse を次のように呼び出すことができます。

package com.rsslldnphy.json

import com.rsslldnphy.models._
import spray.json._

object Json extends DefaultJsonProtocol {
  implicit val personFormat = jsonFormat1(Person)
  implicit val animalFormat = jsonFormat1(Animal)

  def parse[T](s:String)(implicit reader: JsonReader[T]): Option[T] = {
    try { Some(JsonParser(s).convertTo[T]) }
    catch { case e: DeserializationException => None }
  }
}

object JsonFacade {
    def optParse[T]( s: String ): Option[T] = {
      import Json._
      parse[T]( s )
    }
}

optParseここで、暗黙はメソッドのみを「汚染」します。

于 2012-11-11T11:53:32.607 に答える