Scala Pickling 和类型参数

2024-04-04

我在用着斯卡拉酸洗 https://github.com/scala/pickling,Scala 的自动序列化框架。 根据作者的幻灯片 http://lampwww.epfl.ch/~hmiller/files/oopsla-pickling.pdf, 任何类型T只要有隐式的就可以腌制Pickler[T]在适用范围。 在这里,我假设她的意思是scala.tools.nsc.io.Pickler。 但是,以下内容无法编译:

import scala.pickling._
import scala.pickling.binary._
import scala.tools.nsc.io.Pickler

object Foo {
  def bar[T: Pickler](t: T) = t.pickle
}

错误是:

[error] exception during macro expansion:
[error] scala.ScalaReflectionException: type T is not a class
[error]     at scala.reflect.api.Symbols$SymbolApi$class.asClass(Symbols.scala:323)
[error]     at scala.reflect.internal.Symbols$SymbolContextApiImpl.asClass(Symbols.scala:73)
[error]     at scala.pickling.PickleMacros$class.pickleInto(Macros.scala:381)
[error]     at scala.pickling.Compat$$anon$17.pickleInto(Compat.scala:33)
[error]     at scala.pickling.Compat$.PickleMacros_pickleInto(Compat.scala:34)

我正在使用 Scala 2.10.2 和 scala-pickling 0.8-SNAPSHOT。

这是错误还是用户错误?

编辑1:两者都会出现相同的错误scala.pickling.SPickler and scala.pickling.DPickler.

编辑2:看起来这是一个错误:https://github.com/scala/pickling/issues/31 https://github.com/scala/pickling/issues/31


是的,正如安迪指出的:

你需要一个scala.pickling.SPickler https://github.com/scala/pickling/blob/825abf361afb455b3595ff8bf4ce53179458ebd2/core/src/main/scala/pickling/Pickler.scala#L18 or a scala.pickling.DPickler https://github.com/scala/pickling/blob/825abf361afb455b3595ff8bf4ce53179458ebd2/core/src/main/scala/pickling/Pickler.scala#L33(分别是静态和动态)以腌制特定类型。

那些都已经进来了scala.pickling包,因此只需在通用方法签名中使用它们就足够了。

你完全正确,你可以添加一个SPickler上下文绑定到您的通用方法。您需要的唯一额外的东西(不可否认,它有点难看,我们正在考虑删除它)是添加一个FastTypeTag也受上下文限制。 (这对于酸洗框架了解它正在尝试酸洗什么类型是必要的,例如,因为它以不同的方式处理基元。)

这是您需要做的来提供通用的酸洗/取消酸洗方法:

请注意,对于unbar方法,您需要提供一个Unpickler上下文绑定而不是SPickler上下文绑定。

import scala.pickling._
import binary._

object Foo {
  def bar[T: SPickler: FastTypeTag](t: T) = t.pickle
  def unbar[T: Unpickler: FastTypeTag](bytes: Array[Byte]) = bytes.unpickle[T]
}

在 REPL 中对此进行测试,您将得到:

scala> Foo.bar(42)
res0: scala.pickling.binary.BinaryPickle =
BinaryPickle([0,0,0,9,115,99,97,108,97,46,73,110,116,0,0,0,42])

scala> Foo.unbar[Int](res0.value)
res1: Int = 42
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala Pickling 和类型参数 的相关文章

随机推荐