如何评估定义和调用宏的 Julia 表达式?

How to evaluate Julia expression defining and calling a macro?

我正在生成一些代码,稍后将对其进行评估。尽管生成的代码是正确的并且逐行评估它不会导致问题,但它无法作为一个整体正确评估。

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

Returns: ERROR: LoadError: UndefVarError: @m not defined

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

Returns: "return"

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

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

果然,这就是你想要的:

julia> eval(ex)
"return"

由于 Julia 没有局部范围的宏,这个宏定义必须已经发生在全局范围内,所以大概它应该在原始宏可以工作的任何地方工作——即宏定义应该在顶级复合表达式有效的所有相同位置有效。