The HDF5.jl https://github.com/timholy/HDF5.jl包必须处理这个问题。它解决了它 https://github.com/timholy/HDF5.jl/blob/76e0265faec79ca5d11b8fb0678169c132fd322e/src/JLD.jl#L834-L842通过解析字符串然后检查结果before eval
荷兰国际集团它。如果解析后的字符串是它所认为的valid_type_expression https://github.com/timholy/HDF5.jl/blob/76e0265faec79ca5d11b8fb0678169c132fd322e/src/JLD.jl#L761-L765然后它知道在中进行评估应该是安全的Main
命名空间。这允许它从主命名空间中获取自定义类型,而这些类型在baremodule
.
更多详细信息:解析任意字符串后,您可以检查返回的对象以查看其评估是否“安全”:
julia> dump(parse("Int"))
Symbol Int
julia> dump(parse("Vector{Int}"))
Expr
head: Symbol curly
args: Array(Any,(2,))
1: Symbol Vector
2: Symbol Int
typ: Any
julia> dump(parse("""rm("/")"""))
Expr
head: Symbol call
args: Array(Any,(2,))
1: Symbol rm
2: ASCIIString "/"
typ: Any
我们要确保我们永远不会eval
可以调用任意行为的表达式。根据您想要支持类型语法的彻底程度,您的解决方案可能非常简单,也可能像我上面链接的 HDF5 解决方案一样复杂。如果您只是追求简单的、非参数化的类型,我们可以大大简化事情:
is_valid_type_expression(ex::Symbol) = true
is_valid_type_expression(ex) = false
function julia_type(string)
ex = parse(string)
if is_valid_type_expression(ex)
try
typ = eval(Main, ex)
isa(typ, Type) && typ <: Number && return typ
end
end
error("unsupported type: $string")
end
julia> julia_type("String")
ERROR: unsupported type: String
in julia_type at none:9
julia> julia_type("Int")
Int64
julia> julia_type("""rm("/")""")
ERROR: unsupported type: rm("/")
in julia_type at none:9
请注意,任何比符号更复杂的东西都是不允许的eval
编辑。之后eval
解析表达式时,我们检查以确保该类型是 Type 并且是 Type 的子类型Number
。这也将允许自定义子类型Number
除了内置的之外,因为我们正在评估它Main
命名空间。