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

keo*_*orn 5 metaprogramming julia

我正在生成一些代码,稍后将对其进行评估。即使生成的代码是正确的,并且逐行对其进行评估也不会引起问题,但仍不能整体上正确对其进行评估。

eval(quote
  macro m() "return" end
  @m()
end)
Run Code Online (Sandbox Code Playgroud)

返回值: ERROR: LoadError: UndefVarError: @m not defined

eval(quote macro m() "return" end end)
eval(@m())
Run Code Online (Sandbox Code Playgroud)

返回值: "return"

Ste*_*ski 5

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

ex = Expr(:toplevel,
    :(macro m() "return" end),
    :(@m())
)
Run Code Online (Sandbox Code Playgroud)

确实,这可以满足您的需求:

julia> eval(ex)
"return"
Run Code Online (Sandbox Code Playgroud)

由于Julia没有本地范围的宏,因此此宏定义必须已经在全局范围内进行,因此大概可以在原始宏可以使用的任何地方使用,即,宏定义在与top相同的所有位置均有效级复合表达式有效。