Reputation: 614
If I have, say, abstract Component
and want a vector of any of its subtype types, how should I specify Vector
's type parameter? This naive snippet doesn't work:
type Position<:Component
x::Real
y::Real
end
v = Vector{Type{Component}}
push!(v, Position)
ERROR: MethodError: `push!` has no method matching push (::Type{Array{Type{Component},1}}, ::Type{Position})
Closest candidates are:
push!(::Any, ::Any, ::Any)
push!(::Any, ::Any, ::Any, ::Any...)
push!(::Array{Any,1}, ::ANY)
Upvotes: 4
Views: 326
Reputation: 7893
Edit: Tovio's interesting answer is correct, I completely misunderstood the question.
In order to create an empty Vector{Component}
you need to do something like this:
julia> abstract Foo
julia> v₁ = Foo[]
0-element Array{Foo,1}
julia> v₂ = Vector{Foo}()
0-element Array{Foo,1}
julia> v₃ = Array(Foo, 0)
0-element Array{Foo,1}
julia> @assert v₁::Vector{Foo} == v₂::Vector{Foo} == v₃::Vector{Foo}
For example:
julia> for T in (:Bar, :Baz, :Qux)
@eval type $T <: Foo end
end
julia> bar, baz, qux = Bar(), Baz(), Qux()
(Bar(),Baz(),Qux())
julia> for obj in ans
push!(v₁, obj)
end
julia> v₁
3-element Array{Foo,1}:
Bar()
Baz()
Qux()
Upvotes: -1
Reputation: 2699
When you get into a situation where you can use a type but not any of it's subtypes, it can be often involved by introducing a type parameter in the right place. The following seems to work:
abstract Component
type Position<:Component
x::Real
y::Real
end
typealias ComponentType{T<:Component} Type{T}
v = Vector{ComponentType}()
push!(v, Position)
Note that we have created a new type ComponentType
to which any subtype of Component
belongs (including Component
itself), through using a type parameter with the typealias
construction.
Now, in practice I'm not sure if you gain much by doing this rather than just letting v = Vector()
; I don't think the extra type information would allow the Julia compiler to perform any particular optimizations in this case.
Upvotes: 3