Проблемы с параметрическими типами

#julia

#джулия

Вопрос:

Я использую Julia 1.5.2 на Win10

версия 1: эта компилируется. Это действительно работает, если все значения Dict имеют тип ‘V’. Но это не совсем то, чего я хочу.

 struct MyData{K,V} 
    data::AbstractVector{<:AbstractDict{<:K,V}}
end
  

версия 2: это то, что я на самом деле хочу, но компилятор выдает UndefVarError: V not defined исключение. Единственное отличие — {<:K,V} vs {<:K,<:V}

 struct MyData{K,V} 
    data::AbstractVector{<:AbstractDict{<:K,<:V}}
end
  

Обновление: Как воспроизвести

 julia> struct MyStruct{K,V}
           data::AbstractVector{<:AbstractDict{<:K,<:V}}
           end

julia> ar = [Dict{String,Any}("a" => 1)]
1-element Array{Dict{String,Any},1}:
 Dict("a" => 1)

julia> MyStruct(ar)
ERROR: UndefVarError: V not defined
Stacktrace:
 [1] MyStruct(::Array{Dict{String,Any},1}) at .REPL[1]:2
 [2] top-level scope at REPL[3]:1
  

Есть идеи, почему это так и как это исправить?

спасибо за вашу помощь

Комментарии:

1. Они оба работают для меня. Можете ли вы показать ошибку, которая выдается?

Ответ №1:

Это должно быть:

 struct MyStructNew{K,V}
    data::AbstractVector{<:AbstractDict{K,V}}
end
  

То есть ваши параметрические типы должны быть конкретными:

Вот тест:

 julia> MyStructNew(ar)
MyStructNew{String,Any}(Dict{String,Any}[Dict("a" => 1)])

julia> MyStructNew([Dict{Number, AbstractString}(3=>"a")])
MyStructNew{Number,AbstractString}(Dict{Number,AbstractString}[Dict(3 => "a")])
  

Если вы действительно хотите, чтобы типы K и V были абстрактными, вы можете использовать свой оригинал struct , но должны предоставить эти типы, чтобы Джулия знала, как создать ваш объект:

 julia> struct MyStruct{K,V}
           data::AbstractVector{<:AbstractDict{<:K,<:V}}
       end

julia> MyStruct{AbstractString,Any}(ar)
MyStruct{AbstractString,Any}(Dict{String,Any}[Dict("a" => 1)])

  

Комментарии:

1. Это работает только в том случае, если AbstractDict имеет K ключей и V значений. Это не работает для ключей <: K или значений <: V.

2. Это работает, потому что оно явно docs.julialang.org/en/v1/manual/constructors /. … Есть предложения, почему неявная версия не работает?

3. какой тип вы ожидаете, что компилятор будет использовать для K и V в неявной версии?

4. Лучший вариант — это мой первый ответ в сочетании с абстрактными типами в Dict конструкторе. Попробуйте ` MyStructNew([Dict{Number, AbstractString}(3=>»a»)])`