7

我正在使用Scala Pickling,这是一个 Scala 的自动序列化框架。根据作者的幻灯片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-pickling 0.8-SNAPSHOT 的 Scala 2.10.2。

这是错误还是用户错误?

scala.pickling.SPickler编辑 1:和都出现相同的错误scala.pickling.DPickler

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

4

2 回答 2

10

是的,正如安迪指出的那样:

您需要 ascala.pickling.SPickler或 a scala.pickling.DPickler(分别为静态和动态)来腌制特定类型。

这些都已经包含在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
于 2013-09-11T16:37:57.457 回答
3

查看项目,您似乎需要 anscala.pickling.SPickler或 a scala.pickling.DPickler(分别为静态和动态)来腌制特定类型。

pickle 方法是宏。我怀疑如果你用 pickle SPickler,宏将需要知道你的类的编译时类型。

因此,您可能需要执行以下操作:

object Foo {
  def bar(t: SomeClass1) = t.pickle
  def bar(t: SomeClass2) = t.pickle
  def bar(t: SomeClass3) = t.pickle
  // etc
}

或者, aDPickler可以解决问题。我怀疑您仍然需要为您的特定类型编写一些自定义酸洗逻辑。

于 2013-09-10T18:24:32.950 回答