如何将参数/设置传递给 Scala 宏?

编程入门 行业动态 更新时间:2024-10-15 12:28:44
本文介绍了如何将参数/设置传递给 Scala 宏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

如何将参数/设置传递给 Scala 宏?

How can parameters/settings be passed to a Scala macro?

这些设置不应该是全局的,而是每个宏调用.

These settings should not be global, but per macro invocation.

我想要的是类似的东西:

What I would like to have is something similar to this:

def a(param: Int) = macro internalMacro("setting 1") def b(param: Int) = macro internalMacro("setting 2")

而 setting 1 和 setting 2 应该是常量值,可从宏内部访问,因此我可以使内部行为依赖于它们.

whereas setting 1 and setting 2 should then be constant values, accessible from within the macro, so I can make the internal behavior dependent on them.

推荐答案

你的方法的参数列表和宏定义必须完全对齐,宏定义方法有一个额外的上下文初始参数列表,并且每个来自方法定义的具有相同名称和相同类型的其他参数包装在 c.Expr 中.(但请注意,类型参数列表可能不同.)

The parameter lists of your method and the macro definition have to line up exactly, with the macro definition method having an extra initial parameter list for the context, and every other parameter from the method definition having the same name and the same type wrapped in a c.Expr. (Note however that the type parameter lists can differ.)

这意味着您不能将信息作为方法定义中的参数传递给宏实现.不过,您可以使用静态注释来完成同样的事情(这是我从 Eugene Burmako 那里学到的一个技巧,他用它来实现没有反射访问的结构类型,又名 吸血鬼方法):

This means that you can't pass information to the macro implementation as arguments in your method definition. You can use a static annotation to accomplish the same thing, though (this is a trick I learned from Eugene Burmako, who used it to implement structural types without reflective access, a.k.a. vampire methods):

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 } }

然后:

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) ^

我什至没有检查任何封闭的树木.请参阅我的博客文章此处,了解此方法的实际应用示例.

And I didn't even examine any enclosing trees. See my blog post here for an example of this approach in action.

更多推荐

如何将参数/设置传递给 Scala 宏?

本文发布于:2023-11-25 20:45:28,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1631285.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何将   参数   Scala

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!