2

使用 JSON 组合器时,可以使用文档lazyWrite中所述的方法创建递归结构:

implicit lazy val userWrites: Writes[User] = (
  (__ \ "name").write[String] and
  (__ \ "friends").lazyWrite(Writes.seq[User](userWrites))
)(unlift(User.unapply))

在实现写入时是否可以这样做,即:

implicit lazy val userWrites: Writes[User] = new Writes[User]{
    def writes(user: User) = Json.obj(
        "name" -> user.name,
        "friends" -> ??????
    )
}
4

1 回答 1

2

是的。事实上,相当容易。

implicit lazy val userWrites: Writes[User] = new Writes[User] {
    def writes(user: User) = Json.obj(
        "name" -> user.name,
        "friends" -> user.friends
    )
}


val joe = User("Joe", Nil)
val bob = User("Bob", Nil)
val jane = User("Jane", Seq(bob, joe))
val james = User("James", Seq(bob, jane))

scala> Json.toJson(james)
res0: play.api.libs.json.JsValue = {"name":"James","friends":[{"name":"Bob","friends":[]},{"name":"Jane","friends":[{"name":"Bob","friends":[]},{"name":"Joe","friends":[]}]}]}

userWrites也不需要偷懒。它像这样工作得很好,因为组合器试图通过隐式解析子写入并沿着树向下工作来生成写入,这就是为什么它需要lazyWrite阻止它在递归结构中无限下降的原因。当write 时def writes,我们明确说明 writes 是什么。

但是,两者都无法将您从这种情况中拯救出来:

def jim: User = User("Joe", Seq(dwight))
def dwight: User = User("Bob", Seq(jim))
于 2015-03-12T13:30:35.697 回答