ahm*_*hm5 5 macros dictionary expression julia
macro test1(name,arg)
println(arg.args[2])
typeof(arg.args[2])
end
@test1 test1 (
(arg1, (:max=>10))
)
Run Code Online (Sandbox Code Playgroud)
我有上面的宏,我试图传递一个 Dict 参数作为第二个参数。但问题是我无法访问它。该宏始终将第二个参数解释为表达式,当我尝试访问它时arg.args[2].args,它显示:
Vector{Any} (alias for Array{Any, 1})
Run Code Online (Sandbox Code Playgroud)
所以我不知道如何按原样传递字典。
我只想得到第二个参数,例如:
Dict{Symbol, Int64} with 1 entry:
:max => 10
Run Code Online (Sandbox Code Playgroud)
这是因为宏在代码编译之前就对代码起作用。源代码首先被解析为Symbols、文字(整数、浮点数、字符串等)或Expr(表达式)。此时,所有表达式仅包含这三件事。** 宏完成并返回表达式后,该表达式被编译为运行时代码,其中Dict可以存在更复杂的对象(如 s)。
下面的代码说明了编译前后的差异。请注意宏体中的1+5和were 表达式,但随后被评估为 an和 a 。Dict()Int64Dict
# splat arbitrary number of Expr
macro peekExpr(expr1, expr2, expr3tuple...)
println(typeof(expr1), " ", expr1)
println(typeof(expr2), " ", expr2)
println(typeof(expr3tuple), " ", expr3tuple)
:($expr1, $expr2, $expr3tuple)
end
evaluated = @peekExpr 1+5 Dict() Int64 10 max::Int64
#= printout
Expr 1 + 5
Expr Dict()
Tuple{Symbol,Int64,Expr} (:Int64, 10, :(max::Int64))
=#
for item in evaluated println(typeof(item), " ", item) end
#= printout
Int64 6
Dict{Any, Any} Dict{Any, Any}()
Tuple{Symbol,Int64,Expr} (:Int64, 10, :(max::Int64))
=#
Run Code Online (Sandbox Code Playgroud)
**PS:请记住,Expr如果将运行时对象插入其中,则可以包含其他对象(x = Dict(); :(a in $x).args[end]vs :(a in Dict()).args[end])。只是宏在可以访问运行时对象的阶段不起作用。@peekExpr $x只会看到一个Expr(:$, :x).