为啥 Json.writes[T] 需要一个 `apply` 方法?
Posted
技术标签:
【中文标题】为啥 Json.writes[T] 需要一个 `apply` 方法?【英文标题】:Why does Json.writes[T] require an `apply` method?为什么 Json.writes[T] 需要一个 `apply` 方法? 【发布时间】:2015-11-10 05:23:14 【问题描述】:我有一些扩展此类的案例类:
class CitySuggestion(val name: String, val locationId: String, val locationKind: String)
我想使用 Json.writes[CitySuggestion]
作为这个类的 JSON 编写器,所以我在它的伴生对象中定义了一个 unapply
方法:
object CitySuggestion
def unapply(cs: CitySuggestion): Option[(String, String, String)] =
Some((cs.name, cs.locationId, cs.locationKind))
我认为这样就足够了,但编译器现在也要求提供 apply
方法:
未找到应用函数 [错误] 隐式惰性 val citySuggestionWrites = Json.writes[CitySuggestion]
为什么需要一个 apply 方法?我不想反序列化 JSON,我必须添加逻辑来确定它应该反序列化到哪个子类的实例。
【问题讨论】:
如果您将CitySuggestion
设为案例类,则无需手动定义任何一种方法,尽管您的用例可能会阻止这种情况。
@greggory.hz 谢谢,我不能让它成为一个案例类,因为我正在扩展那个类
【参考方案1】:
发生这种情况是因为 Play Json 的 writes
和 reads
宏共享一个 common implementation. 在此实现中,为 Json.writes[A]
提供的类型 A
会检查其 apply 方法,该方法又用于生成 apply对于Writes
实例。
作为使用“写入”宏的替代方法,您可以创建自己的 Write[CitySuggestion]
,如下所示:
import play.api.libs.json._
import play.api.libs.functional.syntax._
implicit val citySuggestionWrites: Writes[CitySuggestion] = (
(JsPath \ "name").write[String] and
(JsPath \ "locationId").write[String] and
(JsPath \ "locationKind").write[String]
)(unlift(CitySuggestion.unapply))
【讨论】:
以上是关于为啥 Json.writes[T] 需要一个 `apply` 方法?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 HashSet<T> 没有实现 ICollection?