Emi*_*elt 10 scala parameter-passing scala-macros
如何将参数/设置传递给Scala宏?
这些设置不应该是全局的,而是每次宏调用.
我想要的是类似的东西:
def a(param: Int) = macro internalMacro("setting 1")
def b(param: Int) = macro internalMacro("setting 2")
Run Code Online (Sandbox Code Playgroud)
而setting 1和setting 2应然后是恒定值,从宏观中访问,这样我就可以使内部行为依赖于他们.
Tra*_*own 12
您的方法和宏定义的参数列表必须准确对齐,宏定义方法具有上下文的额外初始参数列表,并且方法定义中的每个其他参数具有相同的名称和相同的类型包装在c.Expr.(但请注意,类型参数列表可能不同.)
这意味着您无法将信息作为方法定义中的参数传递给宏实现.你可以使用静态注释来完成同样的事情(这是我从Eugene Burmako那里学到的一个技巧,他使用它来实现没有反射访问的结构类型,也就是吸血鬼方法):
import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
class setting(value: String) extends StaticAnnotation
def internalMacro(c: Context)(param: c.Expr[Int]) = {
import c.universe._
val settingValue = c.macroApplication.symbol.annotations.filter(
_.tree.tpe <:< typeOf[setting]
).headOption.flatMap(
_.tree.children.tail.collectFirst {
case Literal(Constant(s: String)) => s
}
).getOrElse(
c.abort(c.enclosingPosition, "Annotation body not provided!")
)
settingValue match {
case "setting 1" => c.Expr(q"42")
case _ => param
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
scala> @setting("setting 1") def a(param: Int): Int = macro internalMacro
defined term macro a: (param: Int)Int
scala> @setting("setting 2") def b(param: Int): Int = macro internalMacro
defined term macro b: (param: Int)Int
scala> def c(param: Int): Int = macro internalMacro
defined term macro c: (param: Int)Int
scala> a(10)
res0: Int = 42
scala> b(10)
res1: Int = 10
scala> c(10)
<console>:22: error: Annotation body not provided!
c(10)
^
Run Code Online (Sandbox Code Playgroud)
我甚至没有检查任何封闭的树木.请参阅我的博客文章,了解此方法的实例.
| 归档时间: |
|
| 查看次数: |
2002 次 |
| 最近记录: |