scala – 有效地序列化案例类
发布时间:2020-12-16 08:52:05 所属栏目:安全 来源:网络整理
导读:对于我正在研究的库,我需要提供一种有效,方便且类型安全的序列化 scala类的方法.理想的情况是,如果用户可以创建一个案例类,并且只要所有成员都是可序列化的,那么它应该也是如此.我确切地知道序列化和反序列化阶段的类型,因此不需要(并且不能承受)任何“模式
对于我正在研究的库,我需要提供一种有效,方便且类型安全的序列化
scala类的方法.理想的情况是,如果用户可以创建一个案例类,并且只要所有成员都是可序列化的,那么它应该也是如此.我确切地知道序列化和反序列化阶段的类型,因此不需要(并且不能承受)任何“模式”信息作为序列化格式的一部分(如
Java对象序列化).
我一直在玩一些想法,这个似乎非常接近.我在这里看到的主要问题是用户如何指定类的“apply”和“unapply”函数.由于这些都是静态函数,我想知道是否有可能让编译器找到它. 这是一个自包含的例子: trait InOut[T] { // just keeping things simple,for illustration purposes def toWire(x: T): Array[Byte] def fromWire(v: Array[Byte] ): T } object InOutConversions { // Pretend these are implemented properly implicit def Int = new InOut[Int] { def toWire(x: Int): Array[Byte] = Array[Byte]() def fromWire(v: Array[Byte] ): Int = 44 } implicit def String = new InOut[String] { def toWire(x: String): Array[Byte] = Array[Byte]() def fromWire(v: Array[Byte] ): String = "blah" } // etc... for all the basic types } 然后我需要一个这样的函数: def serialize2[T,A1 : InOut,A2 : InOut](unapply : T => Option[Product2[A1,A2]])(obj : T) : Array[Byte] = { val product : Product2[A1,A2] = unapply(obj).get implicitly[InOut[A1]].toWire(product._1) ++ implicitly[InOut[A2]].toWire(product._2) } 这将允许用户非常容易地使用它.例如 case class Jesus(a: Int,b: String) val j = Jesus(4,"Testing") serialize2 (Jesus.unapply(_)) (j) 但正如你所看到的那样,最后一行确实非常糟糕.当然有必要改进吗? (鉴于耶稣,我当然可以找到’unapply’静态方法) 解决方法
因为没有获取给定案例类的伴随对象的通用方法,所以您将添加一些额外的工作.我看到三个选项:
>你可以使用结构类型,但是你会失去性能 例如: trait ToTuple2[A1,A2] { def toTuple: (A1,A2) } case class Jesus(a: Int,b: String) extends ToTuple2[Int,String] { val toTuple = (a,b) } def serialize2[T <: ToTuple2[A1,A2],A2 : InOut](obj : T): Array[Byte] = { val product : Product2[A1,A2] = obj.toTuple implicitly[InOut[A1]].toWire(product._1) ++ implicitly[InOut[A2]].toWire(product._2) } 选项2的代码示例: case class Jesus(a: Int,b: String) trait Unapply2[T,A1,A2] { def asTuple( t: T ): (A1,A2) } implicit val UnapJesus = new Unapply2[Jesus,Int,String] { def asTuple( j: Jesus ) = Jesus.unapply(j).get } def serialize2[T,A2](obj : T) (implicit unap: Unapply2[T,inout1: InOut[A1],inout2: InOut[A2]) : Array[Byte] = { val product : Product2[A1,A2] = unap.asTuple(obj) inout1.toWire(product._1) ++ inout2.toWire(product._2) } 你应该看看SBinary,它看起来很相似. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |