Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用scala argonaut编码嵌套类_Scala_Argonaut - Fatal编程技术网

使用scala argonaut编码嵌套类

使用scala argonaut编码嵌套类,scala,argonaut,Scala,Argonaut,我正在尝试对下面的案例进行编码/解码 case class Person(name: String, age: Int, childs: List[Person]) 使用以下代码: object Person { implicit def PersonCodecJson = casecodec3(Person.apply, Person.unapply)("name", "age", "childs") } 使用argonaut,但我得到以下编译器错误: could

我正在尝试对下面的案例进行编码/解码

case class Person(name: String, age: Int, childs: List[Person])
使用以下代码:

object Person {
    implicit def PersonCodecJson =
        casecodec3(Person.apply, Person.unapply)("name", "age", "childs")

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

could not find implicit value for evidence parameter of type argonaut.EncodeJson[List[Person]]
显然,编译器不知道如何处理List[Person]的编码,因为它在如何编码Person的定义中使用

有没有聪明的方法告诉argonaut如何正确编码

更新:多亏了特拉维斯:它现在正在编译,但不起作用

implicit def PersonCodecJson : CodecJson[Person] =
        casecodec3(Person.apply, Person.unapply)("name", "age", "childs")
导致试图解码的无限递归和堆栈溢出

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)
导致

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的方法有效吗?我必须完全不同地处理它吗?或者只是缺少了一小段代码?

非常接近,只需明确指定类型:

object Person {
  implicit def PersonCodecJson: CodecJson[Person] =
    casecodec3(Person.apply, Person.unapply)("name", "age", "childs")
}
正如Scala不允许在没有显式结果类型的情况下编写递归方法一样,它也不会在没有显式结果类型的定义中找到所定义的隐式方法


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

显然问题在于
casecode
。如果您手动创建解码器,它可以工作:

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()))
implicit def PersonDecodeJson:DecodeJson[Person]=
DecodeJson(c=>for{

名称谢谢Travis!它现在正在编译,但仍然不起作用。在尝试解码嵌套结构时,我面临堆栈溢出。我相应地更新了我的问题。哦,对了。Play的JSON库为这种情况提供了一个
lazyRead
方法,但我不确定Argonaut中是否有类似的方法。可能值得一提在邮件列表或GitHub上。