出于某种原因,我必须在宏中放置quote
... end
块,并以编程方式生成ex
。这段代码有效。
macro addsum_out()
quote
ex = :(x+y)
sum(eval(ex))
end
end
x = [1 1 1]
y = [2 2 2]
z2 = @addsum_out
将宏放入模块时,它不再有效:
module MyModule
export @addsum
macro addsum()
quote
ex = :(x+y)
sum(eval(ex))
end
end
end
using MyModule
x = [1 1 1]
y = [2 2 2]
z = @addsum
它说:
ERROR: LoadError: UndefVarError: x not defined
我想我应该将esc
放在某处,以评估模块外部主范围中的表达式ex
。我该怎么办呢?
答案 0 :(得分:4)
这里的问题是引用x
的宏(在模块内)将在该模块中查找x
,例如MyModule.x
这是macro hygiene的一部分。
为防止宏观卫生发生,您需要esc(x)
- 这意味着它将使用呼叫站点范围内的任何x。
您的完整解决方案可能如下所示:
macro addsum_out()
quote
esc(x) + esc(y)
end
end
或更简洁:
macro addsum_out()
:( esc(x) + esc(y) )
end
请注意,这与执行esc( :(x+y) )
功能的+
略有不同。即包含此宏的模块可能包含+
的重载,如果您想使用它,则不要转义+
,否则请执行!
我在一本指南中对这个主题进行了一些讨论:
https://github.com/p-i-/MetaGuideJulia/wiki#example-swap-macro-to-illustrate-esc