(对于 TL;DR,请转到粗体部分)
我有一个带有序列化的干净封闭类型类系统(与 POJO 序列化问题分离)。例如:
trait Expr
case class Const(i: Int) extends Expr
case class BinOp(a: Expr, b: Expr, op: Int) extends Expr
但在某些情况下,我需要捕获一个闭包。例如:
case class Map(a: Expr, fun: Expr => Expr) extends Expr
现在,我用 POJO 序列化(ObjectOutputStream
等)解决了这个问题fun
。我的脚被严重咬伤,因为我无法在 Scala 2.10 中阅读我在 2.9 中序列化的内容。在这种情况下,我真的需要确保我可以独立于 Scala 版本来取回我的东西。
所以......我一直在想我可以使用宏来“备份”源代码,这样如果 POJO 反序列化失败,我可以从源代码重新生成函数(使用就地编译器/解释器)。
我的想法是
object Map {
def apply(a: Expr, fun: Expr => Expr): Map = macro applyImpl
private def applyImpl = ???
def unapply(m: Map): Option[(Expr, Expr => Expr)] = Some(m.a -> m.fun)
}
trait Map extends Expr {
def a: Expr
def fun: Expr => Expr
}
implicit class ExprOps(val ex: Expr) extends AnyVal {
def map(fun: Expr => Expr) = Map(ex, fun)
}
是否可以轻松捕获呼叫的来源,例如
// |------------- source of this -------------|
someExpr.map { case Const(i) => Const(i*i); case x => x }
(我的猜测是 def-macro 需要已经在 的map
函数中ExprOps
)。