为什么宏不能理解 Dict 参数?

why could macros not understand a Dict parameter?

macro test1(name,arg)
    println(arg.args[2])
    typeof(arg.args[2])
end 

@test1 test1 (
  (arg1, (:max=>10))
)

我有上面的宏,我正在尝试传递一个 Dict 参数作为第二个参数。但问题是我无法访问它。宏将始终将第二个参数解释为表达式,当我尝试访问 arg.args[2].args 时,它显示:

Vector{Any} (alias for Array{Any, 1})

所以我不知道如何按原样传递 Dict。

我只想得到第二个参数,例如:

Dict{Symbol, Int64} with 1 entry:
  :max => 10

这是因为宏在编译代码之前对代码起作用。源代码首先被解析为 Symbols、文字(整数、浮点数、字符串等)或 Expr(表达式)。此时,所有表达式只包含这三样东西。**在完成宏和 returns 表达式后,该表达式被编译到运行时代码中,其中可以存在更复杂的对象,如 Dicts。

下面的代码说明了编译前后的区别。请注意 1+5Dict() 是如何在宏主体中作为表达式,但随后被计算为 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))
=#

**PS:请记住,如果将运行时对象插入其中,Expr 可以包含其他对象(x = Dict(); :(a in $x).args[end]:(a in Dict()).args[end])。只是宏在可以访问运行时对象的阶段不起作用。 @peekExpr $x 只会看到一个 Expr(:$, :x).