如何将宏参数传递给同一宏中的表达式?
How to pass a macro-argument to an expression within the same macro?
macro myMacro(name,arg)
:(struct $name
$(esc(arg.args[1]))
function $name(;$(esc(arg.args[1]))=arg.args[2].args[2])
new($(esc(arg.args[1])))
end
end)
end
我正在尝试创建一个具有默认值的结构,该结构作为宏的第二个参数。我知道当我将 arg.args[2].args[2]
定义为默认参数时会出错,因为 arg.args[2].args[2]
未在 struct
中定义,但我不知道如何定义它。
宏应扩展为:
macroexpand(Main,:(@myMacro myM ((arg,(default=10)))))
:(struct myM
arg
function myM(; arg = 10)
new(arg)
end)
你很接近,只是几个问题:
此处不需要esc
。通常,为了避免与宏调用范围内的变量发生冲突,宏返回表达式的局部变量被重命名为 gensym
,全局变量取自宏 definition'范围。 esc
为表达式撤消此操作,因此该表达式中的变量可以与宏调用范围混合。在您的情况下,您尝试 esc
的变量是 struct
和 function
的局部变量,无论如何都没有机会与宏调用范围混合。
您忘记插入 arg.args[2].args[2]
位。
macro myMacro(name,arg)
:(struct $name
$(arg.args[1])
function $name(; $(arg.args[1]) = $(arg.args[2].args[2]) )
new( $(arg.args[1]) )
end
end)
end
macro myMacro(name,arg)
:(struct $name
$(esc(arg.args[1]))
function $name(;$(esc(arg.args[1]))=arg.args[2].args[2])
new($(esc(arg.args[1])))
end
end)
end
我正在尝试创建一个具有默认值的结构,该结构作为宏的第二个参数。我知道当我将 arg.args[2].args[2]
定义为默认参数时会出错,因为 arg.args[2].args[2]
未在 struct
中定义,但我不知道如何定义它。
宏应扩展为:
macroexpand(Main,:(@myMacro myM ((arg,(default=10)))))
:(struct myM
arg
function myM(; arg = 10)
new(arg)
end)
你很接近,只是几个问题:
此处不需要
esc
。通常,为了避免与宏调用范围内的变量发生冲突,宏返回表达式的局部变量被重命名为gensym
,全局变量取自宏 definition'范围。esc
为表达式撤消此操作,因此该表达式中的变量可以与宏调用范围混合。在您的情况下,您尝试esc
的变量是struct
和function
的局部变量,无论如何都没有机会与宏调用范围混合。您忘记插入
arg.args[2].args[2]
位。
macro myMacro(name,arg)
:(struct $name
$(arg.args[1])
function $name(; $(arg.args[1]) = $(arg.args[2].args[2]) )
new( $(arg.args[1]) )
end
end)
end