您可以使用以下方式创建自定义包装def macros
器Dynamic
:
import scala.reflect.macros.Context
import scala.language.experimental.macros
def applyDynamicImplementation(c: Context)(name: c.Expr[String])(args: c.Expr[Any]*) : c.Expr[Any] = {
import c.universe._
val nameStr = name match { case c.Expr(Literal(Constant(s: String))) => s }
if (nameStr != "sync")
c.Expr[Any](q"""{
val res = ${c.prefix}.t.${newTermName(nameStr)}(..$args)
${c.prefix}.t.sync
res
}""")
else
c.Expr[Any](q"""${c.prefix}.t.sync""")
}
import scala.language.dynamics
class SyncWrapper[T <: { def sync(): Unit }](val t: T) extends Dynamic {
def applyDynamic(name: String)(args: Any*): Any = macro applyDynamicImplementation
}
您必须为准引号使用编译器插件。如果你想sync
在方法之前调用 - 只需切换val res = ...
和${c.prefix}.t.sync
线路。
用法:
class TestWithSync {
def test(a: String, b: String) = {println("test"); a + b}
def test2(s: String) = {println("test2"); s}
def sync() = println("sync")
}
val w = new SyncWrapper(new TestWithSync)
scala> w.test("a", "b")
test
sync
res0: String = ab
scala> w.test2("s")
test2
sync
res1: String = s
scala> w.invalidTest("a", "b")
<console>:2: error: value invalidTest is not a member of TestWithSync
w.invalidTest("a", "b")
^