如何在Julia中实例化一个结构,其中我在字符串变量中有结构名?

如何在Julia中实例化一个结构,其中我在字符串变量中有结构名?,julia,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

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

例如,如果结构是这样定义的

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

它会起作用的。但是有没有一种更直接的方法,比如
返回struct_name()
,而不是n个if-else语句?我知道朱莉娅支持反思。如何使用它来支持上述用例?

我建议不要在生产代码中使用它,但您可以执行以下操作:

function load(struct_name::AbstractString)
    invoke(eval(Symbol(struct_name)),Tuple{})
end
将在模块的全局范围内通过
eval
解析
strutu\u name


使用@EPo建议的字典更安全。

基于字典的分派示例
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')
, 你可以求助于


作为有关
eval()
风险的补充说明,在。简言之,
eval()
是一个巨大的安全漏洞,是程序设计有问题的“气味”(警告标志)

您可以改用宏:

julia>模块加载
加载时导出
宏加载(结构名称::符号)
返回:($(esc(结构名称)))
结束
结束
主荷载
julia>使用Main.Load:@Load
茱莉亚:画个句号
julia>结构B端
朱莉娅>@加载一个
()
朱莉娅>@macroexpand@load B
:(B())
朱莉娅>@loadc
错误:未定义错误:未定义C
堆栈跟踪:
[1] 无的顶级作用域:0

被认为是字典吗?此外,什么是反射?@EPo reflection基本上允许在运行时检查定义的类型和方法,而不需要在编译时知道类型和方法的名称。在Java等语言中,它还允许实例化对象。例如,请参见此处:@EPo,在这种情况下,我将如何使用词典?请注意,我不想实例化所有的结构并将它们保存在Dict中,而只是实例化传递给函数时所需的结构。您可以基于字典查找调用构造函数,但通常使用这种分派是有风险的,并且通常表明程序的其他部分的工作方式有问题(或数据结构)是专门设计的,因此可能值得再看一看为什么您最终会在调用者的上下文中寻找这样的功能以及如何使用结果。请参见下面的小示例。感谢@BogumiłKamiński,这符合要求。使用此功能时需要注意哪些注意事项/缺点?实际使用
Symbol
在这种情况下,使
eval
比Python中的
eval
安全得多,因为我们告诉Julia要查找与此符号的绑定。但是,还需要采取其他预防措施,例如,它本身速度慢,类型不稳定,在全局范围内解析(可能您也可以在局部范围内绑定到此名称).一般来说-在大多数情况下,这表明您可以使用其他设计。感谢您的输入!通过链接,我了解到使用eval()是一个代码注入问题的安全风险,其中任何字符串都可以被发送用于实例化。因此,现在我将使用没有问题的IF语句本身,也看它是否真的需要,并且没有其他选择。编写一个可以考虑的简单模式是<代码> DICT(符号(Fun))。=>在[sin,cos,abs]中玩得开心。。将字符串作为键
Dict(string(Symbol(fun))=>在[sin,cos,abs]中玩得开心。