为什么宏不能理解 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
这是因为宏在编译代码之前对代码起作用。源代码首先被解析为 Symbol
s、文字(整数、浮点数、字符串等)或 Expr
(表达式)。此时,所有表达式只包含这三样东西。**在完成宏和 returns 表达式后,该表达式被编译到运行时代码中,其中可以存在更复杂的对象,如 Dict
s。
下面的代码说明了编译前后的区别。请注意 1+5
和 Dict()
是如何在宏主体中作为表达式,但随后被计算为 Int64
和 Dict
.
# 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)
.
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
这是因为宏在编译代码之前对代码起作用。源代码首先被解析为 Symbol
s、文字(整数、浮点数、字符串等)或 Expr
(表达式)。此时,所有表达式只包含这三样东西。**在完成宏和 returns 表达式后,该表达式被编译到运行时代码中,其中可以存在更复杂的对象,如 Dict
s。
下面的代码说明了编译前后的区别。请注意 1+5
和 Dict()
是如何在宏主体中作为表达式,但随后被计算为 Int64
和 Dict
.
# 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)
.