我想生成一个带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?可能是最好的方法吗?
答案 0 :(得分:3)
在第二个示例(不起作用)中,undef_array
是一个数组,其元素未初始化:
julia> undef_array = Array{example2}(undef,3)
3-element Array{example2,1}:
#undef
#undef
#undef
原因是无法实例化类型为example2
的对象,因为您的抽象类型abstract_num
(example2
字段的类型)没有任何具体的子类型因此也无法实例化。结果,即使索引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的命名转换-struct
和DataType
的名称应以大写字母开头。
最后但并非最不重要的是,在第一个给出具体类型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)