解压缩函数中的字典条目

时间:2018-10-11 11:02:19

标签: julia

我想解压缩存储在字典中的参数。之后,它们应该在函数的本地范围内可用。名称应与作为符号的键相同。

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()可行,但在全局范围内需要评估,我想避免。

1 个答案:

答案 0 :(得分:0)

如果要打开包装,最好的方法是直接将它们打开:

function actual_fun(d)
    a = d[:a]
    b = d[:b]
    c = d[:c]
    a+b+c
end

这将是类型稳定,相对快速且可读的

例如,您可以执行以下操作(我为您提供了两个选择,以避免直接分配给abc变量):

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

但再次-我觉得这有点混乱。