Reputation: 927
I've got an abstract type, with subtypes. I'd like to make and add to a Dict that holds the subtypes. Is this doable? What's a better way of achieving this?
Example:
abstract type Cat end
struct Lion <: Cat
manecolour
end
struct Tiger <: Cat
stripewidth
end
cats = Dict{Int, <:Cat}()
gives
ERROR: MethodError: no method matching Dict{Int64,var"#s3"} where var"#s3"<:Cat()
What's the more correct way of doing this?
Upvotes: 4
Views: 380
Reputation: 42214
If the number of Cat
types is small you can avoid using abstract container to boost the performance:
cats = Dict{Int, Cat}()
cats[1] = Lion(12)
cats2 = Dict{Int, Union{subtypes(Cat)...}}()
cats2[1] = Lion(12)
Now testing (I am using Tiger
and Lion
cat types):
julia> @btime $cats[1].manecolour == 12;
25.300 ns (0 allocations: 0 bytes)
julia> @btime $cats2[1].manecolour == 12;
17.434 ns (0 allocations: 0 bytes)
Upvotes: 1
Reputation: 1991
Types are of the type DataType
- except UnionAll
s. So you could do
julia> d = Dict{Int, Union{DataType, UnionAll}}()
Dict{Int64,Union{DataType, UnionAll}}()
julia> for (i, type) in enumerate(subtypes(Integer))
d[i] = type
end
julia> d
Dict{Int64,Union{DataType, UnionAll}} with 3 entries:
2 => Signed
3 => Unsigned
1 => Bool
Upvotes: 1
Reputation: 10984
Just use the abstract type as the container type: cats = Dict{Int, Cat}()
:
julia> cats = Dict{Int, Cat}()
Dict{Int64,Cat}()
julia> cats[1] = Lion(12)
Lion(12)
julia> cats
Dict{Int64,Cat} with 1 entry:
1 => Lion(12)
Upvotes: 5