首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用scala argonaut编码嵌套类

用scala argonaut编码嵌套类
EN

Stack Overflow用户
提问于 2014-03-27 00:10:36
回答 2查看 2.3K关注 0票数 9

我正试图对下面的case类进行编码/解码

代码语言:javascript
复制
case class Person(name: String, age: Int, childs: List[Person])

使用以下代码:

代码语言:javascript
复制
object Person {
    implicit def PersonCodecJson =
        casecodec3(Person.apply, Person.unapply)("name", "age", "childs")

}

使用argonaut,但我得到了以下编译器错误:

代码语言:javascript
复制
could not find implicit value for evidence parameter of type argonaut.EncodeJson[List[Person]]

显然,编译器不知道如何处理ListPerson的编码,因为它在如何编码Person的定义中使用。

有没有一个聪明的方法告诉argonaut如何用正确的方式编码它?

更新:多亏了Travis:它现在正在编译,但不起作用。

代码语言:javascript
复制
implicit def PersonCodecJson : CodecJson[Person] =
        casecodec3(Person.apply, Person.unapply)("name", "age", "childs")

导致无限递归和试图解码的堆栈溢出。

代码语言:javascript
复制
val input = """
    [{"name": "parent1", "age": 31, "childs": [{"name": "child1", "age": 2, "childs": []}]},
     {"name": "parent2", "age": 29, "childs": []}
    ]
    """
val persons = input.decodeOption[List[Person]].getOrElse(Nil)

结果:

代码语言:javascript
复制
at Person$.PersonCodecJson(main.scala:8)
at Person$.PersonCodecJson(main.scala:8)
at Person$.PersonCodecJson(main.scala:8)
at Person$.PersonCodecJson(main.scala:8)
at Person$.PersonCodecJson(main.scala:8)
at Person$.PersonCodecJson(main.scala:8)
at Person$.PersonCodecJson(main.scala:8)
at Person$.PersonCodecJson(main.scala:8)
[debug]     Thread run-main-1 exited.
[debug] Interrupting remaining threads (should be all daemons).
[debug] Sandboxed run complete..
java.lang.RuntimeException: Nonzero exit code: 1
at scala.sys.package$.error(package.scala:27)
at sbt.BuildCommon$$anonfun$toError$1.apply(Defaults.scala:1653)
at sbt.BuildCommon$$anonfun$toError$1.apply(Defaults.scala:1653)
at scala.Option.foreach(Option.scala:236)
at sbt.BuildCommon$class.toError(Defaults.scala:1653)
at sbt.Defaults$.toError(Defaults.scala:35)
at sbt.Defaults$$anonfun$runTask$1$$anonfun$apply$36$$anonfun$apply$37.apply(Defaults.scala:656)
at sbt.Defaults$$anonfun$runTask$1$$anonfun$apply$36$$anonfun$apply$37.apply(Defaults.scala:654)
at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:42)
at sbt.std.Transform$$anon$4.work(System.scala:64)

这种解码嵌套json的方法是否有效?我必须完全不同地处理它吗?还是又少了一小块代码?

EN

回答 2

Stack Overflow用户

发布于 2014-03-27 00:42:04

您非常接近-您只需要显式地指定类型:

代码语言:javascript
复制
object Person {
  implicit def PersonCodecJson: CodecJson[Person] =
    casecodec3(Person.apply, Person.unapply)("name", "age", "childs")
}

正如Scala不允许您在没有显式结果类型的情况下编写递归方法一样,如果没有结果类型,它也不会在定义中定义隐式方法。

不知道这有多聪明,但它有效。

票数 6
EN

Stack Overflow用户

发布于 2014-05-29 12:40:23

显然问题是casecodec。如果手动创建解码器,它可以工作:

代码语言:javascript
复制
implicit def PersonDecodeJson: DecodeJson[Person] =
    DecodeJson(c => for {
      name <- (c --\ "name").as[String]
      age <- (c --\ "age").as[Int]
      childs <- (c --\ "childs").as[List[Person]]
    } yield Person(name, age, childs)) 


val persons = input.decodeOption[List[Person]].getOrElse(Nil)
//> persons  : List[Person] = List(Person(parent1,31,List(Person(child1,2,List()))), Person(parent2,29,List()))
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22675722

复制
相关文章

相似问题

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