Ruslan Prakapchuk
Ruslan Prakapchuk

Reputation: 614

How to specify subtypes of abstract type as type parameters in Julia?

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

Answers (2)

HarmonicaMuse
HarmonicaMuse

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

Toivo Henningsson
Toivo Henningsson

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

Related Questions