我的这段代码的问题是,在传递插值字符串时,宏会失败:
macro t(a, b, c)
quote
println(:c, " = " , $c)
($a, $b, $c)
end
end
function test()
# works:
@t 1 2 3
# doesn't work:
x = π
@t 1 2 "x is $x"
end
test()
test()
c = 3 # works
ERROR: UndefVarError: x not defined
因此,内t
插值x
不可用。有解决方案吗,还是在这里使用宏只是一个坏主意?
为了实现您想要的,您需要使用esc
:
macro t(a, b, c)
quote
local a1 = $(esc(a))
local b1 = $(esc(b))
local c1 = $(esc(c))
println(:c, " = ", c1)
(a1, b1, c1)
end
end
请注意,我定义的变量a1
,b1
以及c1
一次,然后再使用它们。原因是,如果您编写了以下内容:
macro t(a, b, c)
quote
println(:c, " = ", $(esc(c)))
($(esc(a)), $(esc(b)), $(esc(c)))
end
end
这是很自然的事情(或者可能不是:)),您将遇到问题c
,例如两次评估。在此示例中:
julia> macro t(a, b, c)
quote
println(:c, " = ", $(esc(c)))
($(esc(a)), $(esc(b)), $(esc(c)))
end
end
@t (macro with 1 method)
julia> function test()
@t 1 2 rand()
end
test (generic function with 1 method)
julia> test()
c = 0.03771143425073453
(1, 2, 0.1819496773810383)
请注意,将打印一个不同的值并返回不同的值。此问题存在于您的原始宏中(即使它使用了@Bill指出的全局变量):
julia> macro t(a, b, c)
quote
println(:c, " = " , $c)
($a, $b, $c)
end
end
@t (macro with 1 method)
julia> @t 1 2 rand()
c = 0.7021554643798531
(1, 2, 0.6363717837673994)
总的来说,当您使用元编程调试代码时,我认为@code_lowered
和@macroexpand
宏对您将很有用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句