如何在Julia实例化一个字符串变量中具有结构名称的结构?

时间:2019-05-18 06:08:21

标签: julia

要实例化的结构的名称将由调用方传递给我的程序。然后,我需要实例化相同的结构以进行进一步处理。

例如,如果结构定义如下

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语句?我看到朱莉娅支持反思。如何将其用于支持上述用例?

3 个答案:

答案 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