如何在Julia中将抽象类型的子类型指定为类型参数?

时间:2016-03-11 18:23:34

标签: types julia

如果我有abstract Component并想要一个任何子类型类型的向量,我应该如何指定Vector的类型参数?这个天真的片段不起作用:

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)

2 个答案:

答案 0 :(得分:3)

当你遇到可以使用某种类型而不是任何子类型的情况时,通常可以通过在正确的位置引入类型参数来实现它。以下似乎有效:

  "db": {
    "name": "db",
    "connector": "memory",
    "file": "mydata.json"
  }

请注意,我们通过使用 "User": { "dataSource": "MongoDB" } 构造的类型参数,创建了abstract Component type Position<:Component x::Real y::Real end typealias ComponentType{T<:Component} Type{T} v = Vector{ComponentType}() push!(v, Position) 的任何子类型所属的新类型ComponentType(包括Component本身)

现在,在实践中,我不确定你是否通过这样做获得了很多,而不仅仅是让v = Component;我不认为额外的类型信息会允许Julia编译器在这种情况下执行任何特定的优化。

答案 1 :(得分:-1)

编辑: Tovio的有趣回答是正确的,我完全误解了这个问题。

要创建一个空的Vector{Component},您需要执行以下操作:

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}

例如:

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()