如何评估定义和调用宏的 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 没有局部范围的宏,这个宏定义必须已经发生在全局范围内,所以大概它应该在原始宏可以工作的任何地方工作——即宏定义应该在顶级复合表达式有效的所有相同位置有效。
我正在生成一些代码,稍后将对其进行评估。尽管生成的代码是正确的并且逐行评估它不会导致问题,但它无法作为一个整体正确评估。
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 没有局部范围的宏,这个宏定义必须已经发生在全局范围内,所以大概它应该在原始宏可以工作的任何地方工作——即宏定义应该在顶级复合表达式有效的所有相同位置有效。