首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在play-json读/写宏中键入参数

在play-json读/写宏中键入参数
EN

Stack Overflow用户
提问于 2017-03-29 08:41:14
回答 1查看 492关注 0票数 3

我有一个参数化的case类CaseClass[T](name: String, t: T),我希望使用play (2.5)进行序列化/反序列化。

当然,如果我没有T类型的等效值,我就不能这样做,所以我定义

代码语言:javascript
复制
object CaseClass {
  implicit def reads[T: Reads] = Json.reads[CaseClass[T]]
}

但是,我得到了以下编译器错误:

代码语言:javascript
复制
overloaded method value apply with alternatives:
   [B](f: B => (String, T))(implicit fu: play.api.libs.functional.ContravariantFunctor[play.api.libs.json.Reads])play.api.libs.json.Reads[B] <and>
   [B](f: (String, T) => B)(implicit fu: play.api.libs.functional.Functor[play.api.libs.json.Reads])play.api.libs.json.Reads[B]
   cannot be applied to ((String, Nothing) => CaseClass[Nothing])

如果我试图对Json.writes宏执行相同的操作,则会得到错误

代码语言:javascript
复制
type mismatch;
   found   : CaseClass[Nothing] => (String, Nothing)
   required: CaseClass[T] => (String, T)

最令人惊讶的是,当我使用Json.format宏时,两种错误都不会发生。

我知道我有不同的解决方案来解决这个问题(使用Json.format,手工编写我的(反)序列化程序,.),但是我很好奇为什么这里会出现这种情况。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-29 19:39:38

这要么是Json.reads宏、类型推断的限制,要么两者兼而有之。类型推断至少与此有一点关系,因为您可以在错误消息中看到一些被推断为Nothing的内容。

如果使用编译器标志-Ymacro-debug-lite,则可以看到宏生成的AST。

代码语言:javascript
复制
implicit def reads[T](implicit r: Reads[T]): Reads[CaseClass[T]] = 
  Json.reads[CaseClass[T]]

翻译为:

代码语言:javascript
复制
_root_.play.api.libs.json.JsPath.$bslash("name").read(json.this.Reads.StringReads)
  .and(_root_.play.api.libs.json.JsPath.$bslash("t").read(r))
  .apply((CaseClass.apply: (() => <empty>)))

清理干净后,看上去像是:

代码语言:javascript
复制
implicit def reads[T](implicit w: Reads[T]): Reads[CaseClass[T]] = (
  (JsPath \ "name").read(Reads.StringReads) and
  (JsPath \ "t" ).read(r)
)(CaseClass.apply _)

不幸的是,它没有编译,因为没有提供CaseClass.apply的类型参数,并将其推断为Nothing。手动将T添加到apply解决了这个问题,但是宏可能不知道CaseClass[T]中的T很重要。

为了更详细地解决类型推断问题,使用Reads组合器,我们调用FunctionalBuilder.CanBuild2#apply,它需要一个(A1, A2) => B。但编译器无法正确推断A2

对于Writes,有一个类似的问题,我们需要一个B => (A1, A2),但是编译器无法正确推断BA2 (分别是CaseClass[T]T )。

Format需要上述两个函数,编译器能够推理出A2必须是T

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43088507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档