[英]define `Codec` for recursive data structure
I have a class looking like this, 我有一堂这样的课,
case class Foo ( bar: Int, foos: Vector[Foo] )
to define a Codec[Foo]
, I tried this, 定义一个
Codec[Foo]
,我尝试了这个,
def fc = shapeless.Lazy((int32 ~~ vector(fc)).widenOpt( (Foo.apply _).tupled, Foo.unapply _ ))
But this did not work, since scodec throws StackOverflowError
. 但这是行不通的,因为scodec抛出了
StackOverflowError
。 What is the right way of doing this ? 正确的做法是什么?
You'll need the scodec.codecs.lazily
combinator to build recursive codecs (not shapeless.lazily
). 你需要的
scodec.codecs.lazily
组合子建递归编解码器(不shapeless.lazily
)。 For example: 例如:
scala> def fc: Codec[Foo] = lazily((int32 :: vector(fc)).as[Foo])
fc: scodec.Codec[Foo]
scala> val res = fc.encode(Foo(1, Vector(Foo(2, Vector.empty)))).require
res: scodec.bits.BitVector = BitVector(64 bits, 0x0000000100000002)
scala> fc.decode(res)
res2: scodec.Attempt[scodec.DecodeResult[Foo]] = Successful(DecodeResult(Foo(1,Vector(Foo(2,Vector()))),BitVector(empty)))
In scodec 1.8.2 and prior, deriving this codec, instead of defining it explicitly, results in an error at compile time, due to the derivation continuing recursively forever. 在scodec 1.8.2及更高版本中,派生此编解码器而不是明确定义它,由于派生永远持续递归,因此在编译时会导致错误。 As of 1.8.3, this codec can be automatically derived without issue.
从1.8.3版开始,此编解码器可以自动派生而不会出现问题。
For an example of a recursive tree, see this example from scodec source . 有关递归树的示例,请参见scodec source中的示例 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.