我想尝试这样的想法:
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)
是否可以这样做,或者我必须在case class和read combinator中拥有相同数量的字段,这是不可能的
答案 0 :(得分:1)
这里有一些问题。首先,案例类的apply
方法是在它的伴随对象中定义的,而不是案例类本身。第二个问题是,一旦在伴随对象中定义apply
方法,它将导致Obj.apply _
中出现模糊的引用错误。这是因为您的apply
声明是重载,而不是覆盖,因为签名不匹配。
解决此问题的一种方法是从isPossible
的构造函数中删除Obj
,而不是使其成为方法或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
会更好,因为它的计算将在对象创建时完成,而不是在传递给构造函数时。这样可以确保您无法仅使用Obj("test", List(1), true)
的无效状态调用isPossible
。