julia - 在函数中解压 dict 条目
问题描述
我想解压存储在字典中的参数。之后它们应该在函数的本地范围内可用。名称应与作为符号的键相同。
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()
有效,但在我想要避免的全局范围内进行评估。
解决方案
如果你想解压它们,那么最好的方法是直接解压它们:
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
但又一次 - 我觉得这有点乱。
推荐阅读
- mysql - MySql InnoDB 表更新单行需要 1+ 秒
- c# - 如果是另一个具有相同名称的表单打开 C#,则关闭表单
- python - 在这种情况下,我需要树数据类型吗?[井字游戏]
- node.js - curl 中的“troute=t1”cookie 设置是什么?以及如何在 NodeJS 中模拟它
- node.js - 是否可以将 Firestore 查询表示为字符串
- windows - 在 cmake 中获取 Windows 可执行文件的运行时依赖项并安装它们
- google-sheets - 如何修改 Google 表格中重复条目的值
- javascript - 如何保护 API 端点?
- elasticsearch - elastic apm,关闭ssl验证
- node.js - NPM 是否有与 java .war 文件等效的文件?