使用抽象类型时初始化empty \ undef Dict

时间:2018-08-26 14:55:08

标签: julia

我想生成一个带undef值的Dict,以便以后可以在这些键上循环并填写正确的值。我可以通过以下方式使用具体类型初始化这样的Dict,并且一切正常:

currencies = ["USD", "AUD", "GBP"]
struct example
    num::Float64
end
undef_array =  Array{example}(undef,3)
Dict{String,example}(zip(currencies, undef_array))

但是当我的结构体具有抽象类型时,我仍然可以生成undef数组,但不能创建dict。我收到错误消息“ UndefRefError:访问未定义的引用”

abstract type abstract_num end
struct example2
    num::abstract_num
end
undef_array =  Array{example2}(undef,3)
Dict{String,example2}(zip(currencies, undef_array))

尽管可以用具体的数组创建这样的Dict:

struct numnum <: abstract_num
    num::Float64
end
def_array = [example2(numnum(5.0)), example2(numnum(6.0)), example2(numnum(4.5))]
Dict{String,example2}(zip(currencies, def_array))

问题

我的问题是,是否有可能生成依赖于抽象类型的undef值的Dict?可能是最好的方法吗?

2 个答案:

答案 0 :(得分:3)

在第二个示例(不起作用)中,undef_array是一个数组,其元素未初始化:

julia> undef_array =  Array{example2}(undef,3)
3-element Array{example2,1}:
 #undef
 #undef
 #undef

原因是无法实例化类型为example2的对象,因为您的抽象类型abstract_numexample2字段的类型)没有任何具体的子类型因此也无法实例化。结果,即使索引undef_array[1]也会得到UndefRefError,因此zip也将不起作用。

将其与第一种(任意)初始化数组元素的情况进行比较:

julia> undef_array =  Array{example}(undef,3)
3-element Array{example,1}:
 example(1.17014136e-315)
 example(1.17014144e-315)
 example(1.17014152e-315)

undef_array[1]可以正常工作。

话虽如此,我不太确定您在这里想要实现什么。为什么不创建一个mydict = Dict{String, example2}()并在需要时用内容填充呢? (如上所述,您必须先定义abstract_num的具体子类型)

出于性能原因,通常应使用avoid creating types with fields of an abstract type

答案 1 :(得分:1)

尝试:

a=Dict{String,Union{example3,UndefInitializer}}(currencies .=>undef)

但是,对于表示缺失值,通常使用Missing类型:

b=Dict{String,Union{example3,Missing}}(currencies .=>missing)

请注意,typeof(undef)产生UndefInitializer,而typeof(missing)产生Missing-因此在Union中需要Dict类型。您可以在上方(.看到的点(.=>)是著名的Julia点运算符。

此外,我建议保持Julia的命名转换-structDataType的名称应以大写字母开头。

最后但并非最不重要的是,在第一个给出具体类型Float64的示例中,Julia已将数组分配给内存中的某个具体地址-请注意,它可能包含一些垃圾数据(请参阅控制台日志)如下):

julia> undef_array =  Array{example}(undef,3)
3-element Array{example,1}:
example(9.13315366e-316)
example(1.43236026e-315)
example(1.4214423e-316)