0
我需要嚮應用程序中的某些其他方法添加一個方法。有相當多的人。除了直接的方法之外,是否有任何明智的方法來執行此操作 - 手動將方法調用插入到每個方法中?將一個方法調用插入許多其他方法
我需要嚮應用程序中的某些其他方法添加一個方法。有相當多的人。除了直接的方法之外,是否有任何明智的方法來執行此操作 - 手動將方法調用插入到每個方法中?將一個方法調用插入許多其他方法
參見this answer用def macros
執行。
import scala.reflect.macros.Context
import scala.language.experimental.macros
def wrappedImpl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
import c.universe._
import scala.reflect.internal.Flags._
object DefMods{
def unapply(mods: Modifiers): Option[Modifiers] = {
val fs = mods.flags.asInstanceOf[Long]
if ((fs & DEFERRED) == 0 && (fs & STABLE) == 0) Some(mods)
else None
}
}
def wrap(t: Tree) = t match {
case DefDef(DefMods(mods), name, tparams, vparams, tpt, body) if name != nme.CONSTRUCTOR =>
DefDef(mods, name, tparams, vparams, tpt,
q"""
println("before")
val res = $body
println("after")
res""")
case x => x
}
def transform(t: Tree) = t match {
case ClassDef(mods, name, tparams, Template(parents, self, methods)) =>
ClassDef(mods, name, tparams, Template(parents, self, methods.map{wrap(_)}))
case x => x
}
c.Expr[Any](Block(annottees.map(_.tree).map(transform(_)).toList, Literal(Constant(()))))
}
import scala.annotation.StaticAnnotation
class wrapped extends StaticAnnotation {
def macroTransform(annottees: Any*) = macro wrappedImpl
}
你必須使用一個compiler plugin爲quasiquotes。
用法:
@wrapped class Test {
def test() = println("test")
}
scala> new Test().test()
before
test
after
見[此答案](http://stackoverflow.com/a/19972102/406435)。您也可以使用[宏註釋](http://stackoverflow.com/a/19971700/406435)在編譯時自動重寫方法。 – senia