3

私はプレイフレームワークを使用しており、抽象クラスを持っています:

 abstract class Base{...}

コンパニオン オブジェクト内に独自の暗黙的な JSON ライターを持つ

object Base {
   implicit val baseWrites: Writes[Base] = (...)(unlift(Base.unapply))
}

この抽象クラスをサブクラス化します。

case class SubClass{...}

また、そのコンパニオン オブジェクト内に独自の暗黙的な JSON ライターがあります。

object SubClass {
   implicit val subClassWrites: Writes[SubClass] = (...)(unlift(SubClass.unapply))
}

Json.toJson(SubClass) を使用してサブクラス オブジェクトをシリアル化しようとすると、エラーが発生します。

[error]  both value subClassWrites in object SubClass of type => play.api.libs.json.
Writes[models.SubClass]
[error]  and value baseWrites in object Base of type =>        
play.api.libs.json.Writes[models.Base]
[error]  match expected type play.api.libs.json.Writes[models.SubClass]
[error]  Ok(Json.toJson(SubClass.find(id)))

あいまいさを取り除く方法はありますか?

4

1 に答える 1

14

Writes反変型パラメータがあるため、衝突が発生していますA:

trait Writes[-A] extends AnyRef

Writes[Base]のサブクラスであることを意味します - が必要な場所でWrites[SubClass]使用できます。Writes[Base]Writes[SubClass]

問題はここにあります:

val base: Base = new SubClass(...)
val jsBase = Json.toJson(base)

したがってWrites[Base]、のインスタンスをシリアル化できるはずですSubClassADTこの場合、次を使用できます。

sealed trait Base
object Base {
  implicit val baseWrites: Writes[Base] = 
    new Writes[Base]{
      def writes(o: Base): JsValue = o match {
        case s: SubClass => SubClass.writes.writes(s)
        case s: SubClass2 => SubClass2.writes.writes(s)
      }
    }
}

case class SubClass(...) extends Base
object SubClass {
  val writes: Writes[SubClass] = (...)(unlift(SubClass.unapply))
}

case class SubClass2(...) extends Base
object SubClass2 {
  val writes: Writes[SubClass2] = (...)(unlift(SubClass2.unapply))
}

キーワードを使用すると、網羅的でないsealed場合に警告が表示されます。match

于 2014-01-10T04:40:58.947 に答える