假设我有一个案例类:
case class Element(name: String)
和一个具有读取的伴侣类:
object Element {
implicit val elementReads = (
(JsPath / "name").read[String]
)
}
我需要这个对象的地图,所以:
object ElementMap {
def apply(elements: Iterable[Element]) = {
val builder = Map.newBuilder[String, Element]
elements.foreach { x => builder += ((x.name, x)) }
builder result
}
}
最后,我必须创建一个可以从JSON读取的读取:
implicit val elementMapReads = (
(JsPath \ "elements").read[Seq[Element]]
)(ElementMap(_))
但是我收到一条错误消息:
overloaded method value read with alternatives: (t: Seq[Element])play.api.libs.json.Reads[Seq[Element]] <and> (implicit r: play.api.libs.json.Reads[Seq[Element]])play.api.libs.json.Reads[Seq[Element]] cannot be applied to (Iterable[Element] ⇒ Map[String,Element])
答案 0 :(得分:2)
这是一个有效的版本:
case class Element(name: String)
object Element {
implicit val elementReads: Reads[Element] =
(JsPath \ "name").read[String].map(Element.apply)
implicit val elementMapReads: Reads[Map[String, Element]] =
(JsPath \ "elements").read[Seq[Element]].map(ElementMap(_))
}
object ElementMap {
def apply(elements: Iterable[Element]) = {
val builder = Map.newBuilder[String, Element]
elements.foreach { x => builder += ((x.name, x)) }
builder result
}
}
在您的代码中,elementReads
隐含的Reads[String]
是Reads[Element]
,而不是Reads[_]
;一般来说,在play-json中使用显式类型注释会更好,因为有一些需要它们的隐式转换。
此外,Reads[Seq[Element]]
有一个map方法,当你有单字段包装器时很方便,并且还解决了转换Reads[Map[String, Element]]
以创建elementMapReads
的问题。
最后,移动Element
随播广告中的container
应该使其自动可用(即使用时不需要导入);我没有测试它,但据我所知,它应该可以工作。