Вы должны быть осторожны в таких случаях, потому что у вас есть запечатанные черты, поэтому вы должны работать организованно.
Давайте разделим проблему на более мелкие проблемы, Предположим, что вы просто хотите записать свои объекты вJSON.тогда мы сможем решить проблему удаления пустых объектов.
Я добавил больше классов, чтобы прояснить идею:
sealed trait Expression
case object Empty extends Expression
case class NonEmptyExpression(x: Int) extends Expression
sealed trait Statement
case class Return(e: Expression) extends Statement
case class NoReturn(x: Int) extends Statement
Первый шаг (предоставьте средство записи для Expresion):
, чтобы сделать это, вы должны создать писателя для Empty
и NonEmptyExpression
, поэтому мы можем сделать это следующим образом:
val emptyExpressionWrites = new Writes[Empty.type] {
override def writes(e: Empty.type) = Json.obj()
}
val nonEmptyExpressionWrites = Json.writes[NonEmptyExpression]
implicit val expressionWrites = new Writes[Expression] {
override def writes(exp: Expression) = {
exp match {
case Empty => emptyExpressionWrites.writes(Empty)
case nonEmptyExpression: NonEmptyExpression => nonEmptyExpressionWrites.writes(nonEmptyExpression)
}
}
}
Второй шаг (предоставить писателя для Statement):
Вы должны предоставить писателя для Return
и NoReturn
.обратите внимание, что play смог узнать, как создать писателя для Return
, и у него есть Expression
, потому что я определил expressionWriter
как implicit
.теперь он знает, как сериализовать Expression
.
val returnWrites = Json.writes[Return]
val noReturnWrites = Json.writes[NoReturn]
val statementWrites = new Writes[Statement] {
override def writes(s: Statement) = {
s match {
case r: Return => returnWrites.writes(r)
case nr: NoReturn => noReturnWrites.writes(nr)
}
}
}
Давайте проверим это, чтобы убедиться, что оно работает нормально:
val statementWithNonEmpty = Return(NonEmptyExpression(100))
println(s"statementWithNonEmpty Json: ${statementWrites.writes(statementWithNonEmpty).toString()}")
val statementWithEmpty = Return(Empty)
println(s"statementWithEmpty Json: ${statementWrites.writes(statementWithEmpty).toString()}")
Вывод:
StatementWithNonEmpty Json: {"e": {"x": 100}}
StatementWithEmpty Json: {"e": {}}
Последний шаг (созданиеСоставитель списка без пустого):
val listStatementWrites = new Writes[Seq[Statement]] {
override def writes(o: Seq[Statement]) = {
val listWithoutEmpty = o.filter {
case Return(Empty) => false
case _ => true
}
JsArray(listWithoutEmpty.map(statementWrites.writes))
}
}
давайте попробуем это:
val listOfStatements = List(Return(NonEmptyExpression(100)), Return(Empty), Return(NonEmptyExpression(200)))
println(s"listOfStatements: ${listStatementWrites.writes(listOfStatements).toString()}")
вывод:
listOfStatements: [{"e ": {" x ": 100}}, {" e ": {" x ": 200}}]