在这种情况下你应该小心,因为你有密封的特质,所以你应该有条不紊地工作。
让我们将问题分解为更小的问题,假设您只想将对象写入 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
第一步(为表达式提供编写器):
为此,您必须为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)
}
}
}
第二步(为语句提供作者):
您必须为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":{}}
最后一步(创建没有 Empty 的 List writer):
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}}]