10

私はこれを持っています:

package models

import play.api.libs.json._
import play.api.libs.functional.syntax._

object ModelWrites {
    implicit val tmoWrites= Json.writes[TestModelObject]
    implicit val ihWrites = Json.writes[IntHolder]
}

case class TestModelObject(s1:String, s2:String)

case class IntHolder(i1:Int, i2:Int)

trait HasInts {
    val ints: List[IntHolder]
}

私がこれをするとき:

scala> val tmo = new TestModelObject("hello", "world") with HasInts {
  val ints = List(IntHolder(1,2), IntHolder(3,4))
}

scala> Json.toJson(tmo)
res0: play.api.libs.json.JsValue = {"s1":"hello","s2":"world"}

混合されたval'ints'を暗黙的にシリアル化するにはどうすればよいですか?好き:

scala> val someInts = List(IntHolder(8,9), IntHolder(10,11))
someInts: List[models.IntHolder] = List(IntHolder(8,9), IntHolder(10,11))

scala> Json.toJson(someInts)
res1: play.api.libs.json.JsValue = [{"i1":8,"i2":9},{"i1":10,"i2":11}]

注:試してみると:implicit val hasIntsWrites = Json.writes[HasInts] 私は(予想どおり?)次のようになります:

[error] Models.scala:10: No unapply function found
[error]     implicit val hasIntsWrites = Json.writes[HasInts]
[error]                                             ^
4

1 に答える 1

9

ここでは、実験的な「インセプション」機能( )を直接使用することはできません。これはJson.writes[...]、ケースクラスでのみ機能するためです。Writesただし、 Inception提供できるインスタンスに基づいて構築し、ごくわずかな定型文で目的を達成することができます。

このようなケースクラスをインスタンス化するときにトレイトを混在させることが良いアイデアかどうかという質問を無視していることに注意してください。おそらくそうではありませんが、ここで示すアプローチは、より一般的なケースでも機能します。

最初にクラスとインポートを行います(ここでは変更はありません)。

case class TestModelObject(s1: String, s2: String)
case class IntHolder(i1: Int, i2: Int)
trait HasInts { val ints: List[IntHolder] }

import play.api.libs.json._
import play.api.libs.functional.syntax._

次に、優先度の低いすべてのインスタンスをトレイトに入れて、コンパイラが正しいインスタンスを選択するようにする必要があります。これは、とTestModelObject with HasIntsの両方のサブタイプであるためです。TestModelObjectHasInts

trait LowPriorityWritesInstances {
  implicit val tmoWrites = Json.writes[TestModelObject]
  implicit val ihWrites = Json.writes[IntHolder]

  implicit object hiWrites extends OWrites[HasInts] {
    def writes(hi: HasInts) = Json.obj("ints" -> hi.ints)
  }
}

そして今、メインイベント:

object WritesInstances extends LowPriorityWritesInstances {
  implicit val tmowhiWrites = new Writes[TestModelObject with HasInts] {
    def writes(o: TestModelObject with HasInts) =
      tmoWrites.writes(o) ++ implicitly[OWrites[HasInts]].writes(o)
  }
}

これで完了です。

scala> import WritesInstances._
import WritesInstances._

scala> val tmo = new TestModelObject("hello", "world") with HasInts {
     |   val ints = List(IntHolder(1, 2), IntHolder(3, 4))
     | }

scala> println(Json.toJson(tmo))
{"s1":"hello","s2":"world","ints":[{"i1":1,"i2":2},{"i1":3,"i2":4}]}

望んだ通りに。

于 2013-01-03T20:55:00.563 に答える