Scala Pickling:为嵌套结构编写自定义pickler / unpickler
发布时间:2020-12-16 18:16:14 所属栏目:安全 来源:网络整理
导读:我正在尝试编写一个自定义SPickler / Unpickler对来解决当前 scala-pickling的局限性. 我试图挑选的数据类型是一个案例类,其中一些字段已经拥有自己的SPickler和Unpickler实例. 我想在我的自定义pickler中使用这些实例,但我不知道如何. 这是我的意思的一个例
我正在尝试编写一个自定义SPickler / Unpickler对来解决当前
scala-pickling的局限性.
我试图挑选的数据类型是一个案例类,其中一些字段已经拥有自己的SPickler和Unpickler实例. 我想在我的自定义pickler中使用这些实例,但我不知道如何. 这是我的意思的一个例子: // Here's a class for which I want a custom SPickler / Unpickler. // One of its fields can already be pickled,so I'd like to reuse that logic. case class MyClass[A: SPickler: Unpickler: FastTypeTag](myString: String,a: A) // Here's my custom pickler. class MyClassPickler[A: SPickler: Unpickler: FastTypeTag]( implicit val format: PickleFormat) extends SPickler[MyClass[A]] with Unpickler[MyClass[A]] { override def pickle( picklee: MyClass[A],builder: PBuilder) { builder.beginEntry(picklee) // Here we save `myString` in some custom way. builder.putField( "mySpecialPickler",b => b.hintTag(FastTypeTag.ScalaString).beginEntry( picklee.myString).endEntry()) // Now we need to save `a`,which has an implicit SPickler. // But how do we use it? builder.endEntry() } override def unpickle( tag: => FastTypeTag[_],reader: PReader): MyClass[A] = { reader.beginEntry() // First we read the string. val myString = reader.readField("mySpecialPickler").unpickle[String] // Now we need to read `a`,which has an implicit Unpickler. // But how do we use it? val a: A = ??? reader.endEntry() MyClass(myString,a) } } 我真的很感激一个有效的例子. 解决方法
这是一个工作示例:
case class MyClass[A](myString: String,a: A) 请注意,MyClass的type参数不需要上下文边界.只有自定义pickler类需要相应的含义: class MyClassPickler[A](implicit val format: PickleFormat,aTypeTag: FastTypeTag[A],aPickler: SPickler[A],aUnpickler: Unpickler[A]) extends SPickler[MyClass[A]] with Unpickler[MyClass[A]] { private val stringUnpickler = implicitly[Unpickler[String]] override def pickle(picklee: MyClass[A],builder: PBuilder) = { builder.beginEntry(picklee) builder.putField("myString",b => b.hintTag(FastTypeTag.ScalaString).beginEntry(picklee.myString).endEntry() ) builder.putField("a",b => { b.hintTag(aTypeTag) aPickler.pickle(picklee.a,b) } ) builder.endEntry() } override def unpickle(tag: => FastTypeTag[_],reader: PReader): MyClass[A] = { reader.hintTag(FastTypeTag.ScalaString) val tag = reader.beginEntry() val myStringUnpickled = stringUnpickler.unpickle(tag,reader).asInstanceOf[String] reader.endEntry() reader.hintTag(aTypeTag) val aTag = reader.beginEntry() val aUnpickled = aUnpickler.unpickle(aTag,reader).asInstanceOf[A] reader.endEntry() MyClass(myStringUnpickled,aUnpickled) } } 除了自定义pickler类之外,我们还需要一个隐式def,它返回一个专门用于具体类型参数的pickler实例: implicit def myClassPickler[A: SPickler: Unpickler: FastTypeTag](implicit pf: PickleFormat) = new MyClassPickler (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |