两个宏之间的通信
Communicate between two macros
是否可以使用宏 foo
验证宏 bar
被调用了两次?
更多详情:
trait Foo {
foo()
}
class Bar extends Foo {
bar()
bar()
}
我希望它仅在 bar()
被调用两次时编译。
当然——宏可以像任何其他 Scala 代码一样维护可变状态:
import scala.language.experimental.macros
import scala.reflect.macros.Context
object Macros {
var counter = 0
def foo_impl(c: Context)(): c.Expr[Unit] = {
import c.universe._
if (counter == 2) c.Expr[Unit](q"()") else c.abort(
c.enclosingPosition,
"Didn't call bar twice!"
)
}
def bar_impl(c: Context)(): c.Expr[Unit] = {
import c.universe._
counter += 1
c.Expr[Unit](q"()")
}
}
然后:
scala> def bar() = macro Macros.bar_impl
defined term macro bar: ()Unit
scala> def foo() = macro Macros.foo_impl
defined term macro foo: ()Unit
scala> foo()
<console>:14: error: Didn't call bar twice!
foo()
^
scala> bar()
scala> foo()
<console>:14: error: Didn't call bar twice!
foo()
^
scala> bar()
scala> foo()
这似乎是一个非常糟糕的主意,但如果你真的愿意,你可以做到。
是否可以使用宏 foo
验证宏 bar
被调用了两次?
更多详情:
trait Foo {
foo()
}
class Bar extends Foo {
bar()
bar()
}
我希望它仅在 bar()
被调用两次时编译。
当然——宏可以像任何其他 Scala 代码一样维护可变状态:
import scala.language.experimental.macros
import scala.reflect.macros.Context
object Macros {
var counter = 0
def foo_impl(c: Context)(): c.Expr[Unit] = {
import c.universe._
if (counter == 2) c.Expr[Unit](q"()") else c.abort(
c.enclosingPosition,
"Didn't call bar twice!"
)
}
def bar_impl(c: Context)(): c.Expr[Unit] = {
import c.universe._
counter += 1
c.Expr[Unit](q"()")
}
}
然后:
scala> def bar() = macro Macros.bar_impl
defined term macro bar: ()Unit
scala> def foo() = macro Macros.foo_impl
defined term macro foo: ()Unit
scala> foo()
<console>:14: error: Didn't call bar twice!
foo()
^
scala> bar()
scala> foo()
<console>:14: error: Didn't call bar twice!
foo()
^
scala> bar()
scala> foo()
这似乎是一个非常糟糕的主意,但如果你真的愿意,你可以做到。