解析Scala宏修改的作用域中的变量
我正在调查是否有可能进行以下类型的导入 在Scala中:解析Scala宏修改的作用域中的变量,scala,macros,scala-macros,Scala,Macros,Scala Macros,我正在调查是否有可能进行以下类型的导入 在Scala中: def helpers[T] = new { def foo: T = ??? } import helpers[Int]._ 这是一个确定Scala可以使用的某些类型的想法 不能自己推断。 手动扩展的版本可以工作: val m = helpers[Int] import m._ (foo: Int) 但是,我天真的尝试宏失败: import scala.reflect.macros.blackbox.Context object
def helpers[T] = new { def foo: T = ??? }
import helpers[Int]._
这是一个确定Scala可以使用的某些类型的想法
不能自己推断。
手动扩展的版本可以工作:
val m = helpers[Int]
import m._
(foo: Int)
但是,我天真的尝试宏失败:
import scala.reflect.macros.blackbox.Context
object Open {
def open[T](m: Any)(t: T): T = macro open_impl[T]
def open_impl[T](c: Context)(m: c.Tree)(t: c.Tree): c.Tree = {
import c.universe._
val freshName = TermName(c.freshName("import$"))
q"{ val $freshName = $m; import $freshName._; $t }"
}
}
我想到的语法是来自OCaml的让openm in
-语法。
问题是变量的绑定似乎发生在
宏扩展:
import Open._
object Foo { val x = 7 }
open(Foo) { println(x) }
在REPL中失败,原因是:
<console>:16: error: not found: value x
open(Foo) { println(x) }
:16:错误:未找到:值x
开(Foo){println(x)}
有没有办法解决这个问题?宏有可能吗?
或者使用编译器插件?导入$freshName.\ucode>在内部子范围内展开。您可以将整个def宏结果看作是在
{…}
中定义的一组代码,知道所有表达式都是在类
es、特征
s、对象
s或def
s中定义的,您可以定义宏注释,该注释将一些名称作为参数并重写注释体,一旦命名内容被删除,就立即导入其内容defined@Odomontois不对。这是一个黑盒宏,你所说的只有白盒宏是正确的。宏将表达式作为参数“打开”,因此该参数在宏的权限内,即使宏是whitebox,您的投诉也不会成为问题。真正的问题是宏必须在打字机后面运行。打字机试图键入{println(x)}
,注意到x
不存在,因为宏还没有运行,然后消失。如果将-Ybrowse:all
或-Xprint:all
添加到编译器参数,则可以看到它。