使用Scala argonaut编码嵌套类 [英] Encoding nested classes using scala argonaut

查看:113
本文介绍了使用Scala argonaut编码嵌套类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对案例类进行编码/解码

I'm trying to encode/decode following case class

case class Person(name: String, age: Int, childs: List[Person])

使用以下代码:

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

}

使用argonaut,但出现以下编译器错误:

with argonaut, but I'm getting the following compiler error:

could not find implicit value for evidence parameter of type argonaut.EncodeJson[List[Person]]

很显然,编译器不知道如何处理List [Person]的编码,因为它在定义如何编码Person的内部使用.

Obviously, the compiler doesn't know how to handle encoding of List[Person], because it's used inside the definition of how to encode Person.

是否有一种聪明的方法告诉argonaut如何正确编码?

Is there a clever way to tell argonaut how to encode it the right way?

更新:感谢Travis:现在正在编译,但是无法正常工作.

Update: Thanks to Travis: It's compiling now, but it's not working.

implicit def PersonCodecJson : CodecJson[Person] =
        casecodec3(Person.apply, Person.unapply)("name", "age", "childs")

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

leads to an infinite recursion and a stack overflow trying to decode

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进行解码的方法是否有效?我必须解决完全不同的问题吗?还是只是缺少一小段代码?

Is this approach to decode this nested json even valid? Do I have to tackle it completely different? Or is just another small piece of code missing?

推荐答案

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

You're very close—you just need to specify the type explicitly:

object Person {
  implicit def PersonCodecJson: CodecJson[Person] =
    casecodec3(Person.apply, Person.unapply)("name", "age", "childs")
}

就像Scala不允许您在没有显式结果类型的情况下编写递归方法一样,它也不会在没有一个隐式结果类型的情况下在定义中找到隐式定义.

Just as Scala won't allow you to write a recursive method without an explicit result type, it won't find the implicit being defined inside the definition without one.

不知道这有多聪明,但是它可以工作.

Not sure how clever that is, but it works.

这篇关于使用Scala argonaut编码嵌套类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆