Инициализировать пустой \ undef Dict при использовании абстрактных типов - PullRequest
0 голосов
/ 26 августа 2018

Я хочу сгенерировать Dict со значениями undef, чтобы позже я мог перебрать ключи и ввести правильные значения. Я могу инициализировать такой 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))

Вопрос

У меня вопрос: возможно ли сгенерировать Dict со значениями undef типа, который опирается на абстрактный тип? Возможно ли, что является лучшим способом сделать это?

Ответы [ 2 ]

0 голосов
/ 26 августа 2018

Во втором (не работающем) примере 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)

Из соображений производительности в общем случае следует избегать создания типов с полями абстрактного типа .

0 голосов
/ 26 августа 2018

Попробуйте:

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.Точка (.), которую вы видите выше (.=>), является известным оператором Джулии.

Кроме того, я рекомендую придерживаться преобразования именования Джулии - имена struct и DataType должны начинатьсяс большой буквы.

И последнее, но не менее важное: в вашем первом примере, где был указан конкретный тип Float64, Джулия присвоила массив какому-то конкретному адресу в памяти - имейте в виду, что он может содержать некоторые ненужные данные (взгляните на консоль)войти ниже):

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