Scala Play隐式读取捕获null

Scala Play implicit read catch null


我正在使用外部服务,我希望收到一个包含具有三种值的字段的 json:

我需要将 json 反序列化为一个案例 class,在代码的其他地方我需要将其序列化为具有相同字段的 json。
我有隐式读写:

implicit lazy val aReads: Reads[A] = (
  "foo".readNullable[Double]
)(A.apply _)

implicit lazy aWrites: OWrites[A] = (
  "foo".write[Option[Double]]
)

案例class:

case class A(
  foo: Option[Double]
)

正如你想象的那样,问题是当值不存在时我无法 "catch" 并且如果使用 "foo".writeNullable[Double] 作为编写器我无法在它为 null 时捕获(它将永远缺席)。我该如何解决这个问题?

你需要的其实是一个反映三种状态的数据类型:

  • 现在
  • 不存在

实际上有一个nice encoding of this here,在语义上等同于:

sealed trait Tristate[+A]
case class Present[+A](a: A) extends Tristate[A]
case object Absent extends Tristate[Nothing] // this can represent your "null" state
case object NonExisting extends Tristate[Nothing]

链接的小型库在 Tristate 上有很好的组合器,例如 mapflatMapfilter

然后,您可以派生一个 Play decoder/encoder,它将对象置于正确的状态并适当地序列化。