问题描述
如何为我的 People
案例类创建一个 play.api.libs.Reads
?
How can I create a play.api.libs.Reads
for my People
case class?
scala> type Id = Long
defined type alias Id
scala> case class People(names: Set[Id])
defined class People
scala> implicit val PeopleReads: Reads[People] = (
| (__ "names").read[Set[Id]])(People)
<console>:21: error: overloaded method value read with alternatives:
(t: Set[Id])play.api.libs.json.Reads[Set[Id]] <and>
(implicit r: play.api.libs.json.Reads[Set[Id]])play.api.libs.json.Reads[Set[Id]]
cannot be applied to (People.type)
(__ "names").read[Set[Id]])(People)
推荐答案
(...)(People)
语法专为构建参数列表(好吧,从技术上讲,它是一个带有 and
的 Builder
,而不是一个列表),并且想要将 People
构造函数提升到 Reads的应用函子中code> 以便您可以将其应用于这些参数.
The (...)(People)
syntax is designed for when you've built up a list of arguments (well, technically it's a Builder
, not a list) with and
and want to lift the People
constructor into the applicative functor for Reads
so that you can apply it to those arguments.
例如,如果您的 People
类型如下所示:
For example, if your People
type looked like this:
case class People(names: Set[Id], home: String)
你可以写:
implicit val PeopleReads: Reads[People] = (
(__ "names").read[Set[Id]] and
(__ "home").read[String]
)(People)
不过,在您的情况下,People
的构造函数只有一个参数,而您没有使用 和
,因此您没有 Builder[Reads[Set[Id] ~ String]
,你刚刚得到了一个普通的Reads[Set[Id]]
.
In your case, though, the constructor for People
has a single argument, and you haven't used and
, so you don't have a Builder[Reads[Set[Id] ~ String]
, you've just got a plain old Reads[Set[Id]]
.
这很好,因为这意味着你不需要奇怪的应用函子语法——你只需要map
:
This is nice, because it means you don't need the weird applicative functor syntax—all you need is map
:
implicit val PeopleReads = (__ "names").read[Set[Id]].map(People)
大功告成.
这篇关于为 JSON 集类型定义 `Reads`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!