加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 展平任意嵌套的编解码器?

发布时间:2020-12-16 18:14:12 所属栏目:安全 来源:网络整理
导读:作为SCodec的新用户,有一个相当的学习曲线.尽管阅读了源代码和文档,我还是遇到了一些似乎无法解决的问题. 我希望能够将流行的编解码器定义为这样的函数 def packedByte : Codec[Int :: Int :: Int :: HNil] = uint(4) :: uint(2) :: uint(2) 然后将它们组合
作为SCodec的新用户,有一个相当的学习曲线.尽管阅读了源代码和文档,我还是遇到了一些似乎无法解决的问题.

我希望能够将流行的编解码器定义为这样的函数

def packedByte : Codec[Int :: Int :: Int :: HNil] = uint(4) :: uint(2) :: uint(2)

然后将它们组合到更高级别的编解码器中,这样可以对像这样的case类进行解码和编码

case class MyPacket(foo : Boolean,first : Int,second : Int,third : Int,bar : Boolean)
def packet : Codec[MyPacket] = (bool :: packedByte :: bool).as[MyPacket]

但是,这不起作用

Could not prove that shapeless.::[Boolean,shapeless.::[shapeless.::[Int,shapeless.::[Int,shapeless.HNil]]],shapeless.::[Boolean,shapeless.HNil]]] can be converted to/from cmd504.MyPacket.

然而,当我“内联”packedByte时,就像

def packetInline : Codec[MyPacket] = (bool :: uint(4) :: uint(2) :: uint(2) :: bool).as[MyPacket]

一切都按预期编译和工作.我的直觉告诉我,编解码器必须“扁平化”(基于错误消息中的两个HNils),但我无法压缩编解码器本身或内部HList表示.

解决方法

通过考虑在类似情况下如何使用普通的价值级列表来开始推理hlists通常很有用.例如,假设我们有一个值和一个列表:

val x = 0
val xs = List(1,2,3)

我们想在xs之前和之后创建一个包含x的新列表.我们可以使用:和:

scala> x +: xs :+ x
res0: List[Int] = List(0,1,3,0)

要么:

scala> x :: (xs :+ x)
res1: List[Int] = List(0,0)

在Scodec的情况下,没有:运算符,但有::和:,您可以完全像在值级别使用列表版本一样使用它们:

import scodec._,scodec.codecs._,shapeless._

def packedByte: Codec[Int :: Int :: Int :: HNil] =
  uint(4) :: uint(2) :: uint(2)

case class MyPacket(
  foo: Boolean,first: Int,second: Int,third: Int,bar: Boolean
)

def packet: Codec[MyPacket] = (bool :: (packedByte :+ bool)).as[MyPacket]

有可能构建一个嵌套的hlist然后展平它,但是:更加惯用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读