我想解压缩存储在字典中的参数。之后,它们应该在函数的本地范围内可用。名称应与作为符号的键相同。
macro unpack_dict()
code = :()
for (k,v) in dict
ex = :($k = $v)
code = quote
$code
$ex
end
end
return esc(code)
end
function assign_parameters(dict::Dict{Symbol, T}) where T<:Any
@unpack_dict
return a + b - c
end
dict = Dict(:a => 1,
:b => 5,
:c => 6)
assign_parameters(dict)
但是,此代码将引发:
LoadError: UndefVarError: dict not defined
如果我在宏之前定义字典,因为定义了字典,所以它可以工作。
有人知道如何解决这个问题吗?使用eval()
可行,但在全局范围内需要评估,我想避免。
答案 0 :(得分:0)
如果要打开包装,最好的方法是直接将它们打开:
function actual_fun(d)
a = d[:a]
b = d[:b]
c = d[:c]
a+b+c
end
这将是类型稳定,相对快速且可读的
例如,您可以执行以下操作(我为您提供了两个选择,以避免直接分配给a
,b
和c
变量):
called_fun(d) = helper(;d...)
helper(;kw...) = actual_fun(;values(kw)...)
actual_fun(;a,b,c, kw...) = a+b+c
function called_fun2(d::Dict{T,S}) where {T,S}
actual_fun(;NamedTuple{Tuple(keys(d)), NTuple{length(d), S}}(values(d))...)
end
现在您可以编写如下内容:
julia> d = Dict(:a=>1, :b=>2, :c=>3, :d=>4)
Dict{Symbol,Int64} with 4 entries:
:a => 1
:b => 2
:d => 4
:c => 3
julia> called_fun(d)
6
julia> called_fun2(d)
6
但是我不建议这样做-它类型不稳定且可读性不强。
AFACT的其他可能性将具有与编译时类似的缺点,Julia仅知道变量的类型而不知道它们的值。
编辑:您可以执行以下操作:
function unpack_dict(dict)
ex = :()
for (k,v) in dict
ex = :($ex; $k = $v)
end
return :(myfun() = ($ex; a+b+c))
end
runner(d) = eval(unpack_dict(d))
然后运行:
julia> d = Dict(:a=>1, :b=>2, :c=>3, :d=>4)
Dict{Symbol,Int64} with 4 entries:
:a => 1
:b => 2
:d => 4
:c => 3
julia> runner(d)
myfun (generic function with 1 method)
julia> myfun()
6
但再次-我觉得这有点混乱。