注:私はメタプログラミングの専門家ではありません。
ジェネリック関数ではなく、代わりにマクロまたは生成された関数を使用して、このようなことができると思います。
これに基づいて:
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
マクロに渡すことはできないことに注意してください (ここでも、一般的なマクロSymbol
を使用すると、エラーをディスパッチするメソッドが存在する可能性があるため、これが簡単になりますか?):
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
私見の方がいいでしょう。
これが最適ではない理由を誰かが説明してくれたら、とてもありがたいです! この回答はコメントである必要がありましたが、コードが多すぎます。
一般的なマクロと生成された関数で同様のものを実装して、投稿を更新しようとします。