首页 > 解决方案 > 如何评估定义和调用宏的 Julia 表达式?

问题描述

我正在生成一些稍后将被评估的代码。即使生成的代码是正确的并且逐行评估它不会导致问题,它也无法作为一个整体正确评估。

eval(quote
  macro m() "return" end
  @m()
end)

回报: ERROR: LoadError: UndefVarError: @m not defined

eval(quote macro m() "return" end end)
eval(@m())

回报:"return"

标签: juliametaprogramming

解决方案


宏扩展是在求值之前完成的,因此当此代码中发生宏扩展时,块中第一个表达式中的宏定义发生得太晚,无法影响块中第二个表达式的扩展。有一种特殊情况可以满足您的要求::toplevel表达式类型。这会自动用于模块中的顶级全局表达式,但您可以手动构造这种类型的表达式,如下所示:

ex = Expr(:toplevel,
    :(macro m() "return" end),
    :(@m())
)

果然,这就是你想要的:

julia> eval(ex)
"return"

由于 Julia 没有局部范围的宏,因此这个宏定义必须已经在全局范围内进行,因此推测这应该可以在原始宏可以工作的任何地方工作 - 即宏定义应该在所有相同的地方都有效级复合表达式有效。


推荐阅读