json - Play 框架,JSON 读取组合器,具有覆盖的 apply 方法

标签 json scala playframework playframework-2.3

我正在尝试做出这样的想法:

case class Obj(name: String, list: List[Integer], isPossible: Boolean) {    
  override def apply(name: String, list: List[Integer]): Obj = {
    Obj(name, list, list.exists((x: Integer) => x >= 10 && x <= 100))
  }
}

implicit val objReads: Reads[Obj] = (
(__ \ "name").read[String] and
(__ \ "list").read[List[Integer]]
)(Book.apply _)

但它无法编译,它返回一个错误:

Overloaded method value [apply] cannot be applied to  ((String, List[Integer], Boolean) => models.Api.Obj)

是否可以做到这一点,或者只是我必须在案例类和读取组合器中具有相同数量的字段,这是不可能的

最佳答案

这里有一些问题。首先,案例类的 apply 方法是在其伴生对象中定义的,而不是案例类本身。第二个问题是,一旦在伴生对象中定义了 apply 方法,就会在 Obj.apply _ 中导致不明确的引用错误。这是因为您的 apply 声明是重载,而不是覆盖,因为签名不匹配。

解决此问题的一种方法是从 Obj 的构造函数中删除 isPossible,并将其设为方法或 val。您仍然可以以相同的方式访问它。

case class Obj(name: String, list: List[Int]) {
    val isPossible: Boolean = list.exists((x: Int) => x >= 10 && x <= 100)
}

object Obj {
    implicit val objReads: Reads[Obj] = (
        (__ \ "name").read[String] and
        (__ \ "list").read[List[Int]]
    )(Obj.apply _)
}

这带来的唯一问题是 isPossible 将不再包含在 JSON 写入中,可以像这样修复:

implicit val objWrites: Writes[Obj] = (
    (__ \ "name").write[String] and
    (__ \ "list").write[List[Int]] and 
    (__ \ "isPossible").write[Boolean]
)( obj => (obj.name, obj.list, obj.isPossible) )

或者,您可以将重载的 apply 重命名为其他名称,并将其用于 Reads 而不是 Obj.apply。但是,我认为将 isPossible 保留为 val 更好,因为它的计算将在对象创建时完成,而不是在传递给构造函数时完成。这将确保您不能仅使用 isPossible 的无效状态来调用 Obj("test", List(1), true)

关于json - Play 框架,JSON 读取组合器,具有覆盖的 apply 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25710711/

相关文章:

c++ - 接收字符串并使用它来调用 C++ 方法

c++ - 解析jsonarray?

scala - 类型论中的种类与等级

scala - Binding.scala 路由重定向到登录页面

scala - 无法从 Build.scala 访问项目的类/对象

javascript - 包含数组的 JSON 对象

javascript - Angular ng 选项分组依据

generics - 表达继承的不同符号

json - 使用 scala play 将 Json 对象添加到 JSON 数组

scala - IntelliJ IDEA 社区版中的 Play 框架支持