注意:我不是元编程专家!
我认为你可以做这样的事情,而不是使用通用函数,而是使用宏或生成的函数。
基于此:
julia> macro bar(dict)
dump(dict, 10)
end
julia> @bar Dict(:foo => "foo", :bar => "bar", :baz => "baz");
Expr
head: Symbol call
args: Array(Any,(4,))
1: Symbol Dict
2: Expr
head: Symbol =>
args: Array(Any,(2,))
1: Expr
head: Symbol quote
args: Array(Any,(1,))
1: Symbol foo
typ: Any
2: ASCIIString "foo"
typ: Any
3: Expr
head: Symbol =>
args: Array(Any,(2,))
1: Expr
head: Symbol quote
args: Array(Any,(1,))
1: Symbol bar
typ: Any
2: ASCIIString "bar"
typ: Any
4: Expr
head: Symbol =>
args: Array(Any,(2,))
1: Expr
head: Symbol quote
args: Array(Any,(1,))
1: Symbol baz
typ: Any
2: ASCIIString "baz"
typ: Any
typ: Any
我能够做这样的事情,它可以做更多的错误检查,而且通用宏会在开发分支中使这更容易(至少对于错误检查):
julia> macro foo(dict)
blk = Expr(:block)
if dict.head == :call && dict.args[1] == :Dict
for arg in dict.args[2:end]
sym = arg.args[1].args[1]
val = arg.args[2]
push!(blk.args, esc(:($sym = $val)))
end
else
error("Need a Dict{Symbol, Any}")
end
blk
end
julia> @foo Dict(:foo => "foo", :bar => "bar", :baz => "baz");
julia> @show foo bar baz;
foo = "foo"
bar = "bar"
baz = "baz"
julia> let # local scope
@foo Dict(:foo => "foo", :bar => "bar", :baz => "baz")
@show foo bar baz
end;
foo = "foo"
bar = "bar"
baz = "baz"
请注意,您不能创建一个 dict 变量,然后将其传递给@foo
宏(同样,泛型宏可以使这更容易,因为可能有一种方法 for Symbol
also 并调度错误?):
julia> dict = Dict(:foo => "foo", :bar => "bar", :baz => "baz");
julia> @foo dict
ERROR: type Symbol has no field head
此时类似于:
@foo a 1 b 2 c 3
或者
@foo :a=>1 :b=>2 :c=>3
恕我直言会更好。
如果有人向我解释为什么这不是最佳的,我将不胜感激!这个答案应该是一个评论,但它有很多代码。
我将尝试使用通用宏和生成的函数来实现类似的东西并更新帖子。