要实例化的结构的名称将由调用方传递给我的程序。然后,我需要实例化相同的结构以进行进一步处理。
例如,如果结构定义如下
struct A end
我有一个定义为
的函数function load(struct_name::AbstractString)
if struct_name == "A"
return A()
elseif struct_name == "B"
return B()
elseif ..... # and so on
end
end
它将起作用。但是,是否有更直接的方法,例如return struct_name()
而不是n个if else语句?我看到朱莉娅支持反思。如何将其用于支持上述用例?
答案 0 :(得分:2)
我建议不要在生产代码中这样做,但是您可以执行以下操作:
function load(struct_name::AbstractString)
invoke(eval(Symbol(struct_name)),Tuple{})
end
通过strut_name
的 eval
将在模块的全局范围内解决。
按照@EPo的建议使用字典更安全。
答案 1 :(得分:1)
基于字典的分派示例。 Dict("a" => A, "b" => B)[tag]
选择一个构造函数,然后()
对其进行调用。
struct A end
struct B end
function dispatch(tag)
return Dict("a" => A, "b" => B)[tag]()
end
@assert dispatch("a") == A()
如果您关心默认值以处理意外参数,例如dispatch('zzz')
,
您可以求助于get()
。
作为eval()
风险的旁注,neighboring Python question中有一小部分强大的警告参考。简而言之,eval()
是一个很大的安全漏洞,也是对程序进行可疑设计的“气味”(警告标志)。
答案 2 :(得分:0)
您可以改用宏:
julia> module Load
export @load
macro load(struct_name::Symbol)
return :($(esc(struct_name))())
end
end
Main.Load
julia> using Main.Load: @load
julia> struct A end
julia> struct B end
julia> @load A
A()
julia> @macroexpand @load B
:(B())
julia> @load C
ERROR: UndefVarError: C not defined
Stacktrace:
[1] top-level scope at none:0