加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala PlayJson Cyclic Reference

发布时间:2020-12-16 18:08:43 所属栏目:安全 来源:网络整理
导读:上下文 我有一个案例类,它是层次结构中的一个项目,它引用自己是这样的: case class Node( name: String,children: Option[Seq[Node]] = None) 我想要一个PlayJson Format . 通常,您可以这样做: implicit lazy val formatter = Json.format[MyCaseClass] 但
上下文

我有一个案例类,它是层次结构中的一个项目,它引用自己是这样的:

case class Node(
  name:     String,children: Option[Seq[Node]] = None
)

我想要一个PlayJson Format.

通常,您可以这样做:

implicit lazy val formatter = Json.format[MyCaseClass]

但这不起作用.

为什么?

PlayJson使用Scala宏为case类生成一个Format,它将遍历所有字段,当它到达字段child时,它将查找尚未构造的Node的现有格式化程序,以编译错误结束:

No implicit format for Option[Seq[Node]] available.
[error]   implicit lazy val formatter = Json.format[Node]

问题

什么是最好的方法来解决这个问题?
这是PlayJson格式宏的已知问题吗?

解决方法

这是可以在play-json docs中的递归类型下找到的东西:

import play.api.libs.functional.syntax._
import play.api.libs.json.{Reads,Writes,_}

case class Node(name: String,children: Option[Seq[Node]] = None)

implicit lazy val nodeReads: Reads[Node] = (
  (__  "name").read[String] and
  (__  "children").lazyReadNullable(Reads.seq[Node](nodeReads))
)(Node)

implicit lazy val nodeWrites: Writes[Node] = (
  (__  "name").write[String] and
  (__  "children").lazyWriteNullable(Writes.seq[Node](nodeWrites))
)(unlift(Node.unapply))

因为在这种情况下,Reads和Writes是对称的,所以您可以将整个事物创建为单个格式:

implicit lazy val nodeFormat: Format[Node] = (
  (__  "name").format[String] and
  (__  "children").lazyFormatNullable(Reads.seq[Node](nodeFormat),Writes.seq[Node](nodeFormat))
)(Node.apply,unlift(Node.unapply))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读