首页 > 解决方案 > Julia:使用“抽象类型”编写类型的联合

问题描述

我正在尝试编写以下类型的联合:

FloatVector = Union{Array{Float64,1}, DataArray{Float64,1}, Array{Union{Float64, Missings.Missing},1}};

使用抽象类型语法。理想情况下,我想做与此链接类似的事情。我尝试了以下方法,但不幸的是它不起作用:

abstract type FloatVector end
type Array{Float64,1} <: FloatVector end
type DataArray{Float64,1} <: FloatVector end
type Array{Union{Float64, Missings.Missing},1} <: FloatVector end

我对抽象类型没有信心,也找不到关于类似问题的好的参考。如果您能向我解释如何进行以及相对于联盟的优势,我将很高兴。

标签: julia

解决方案


在 Julia 中使用抽象类型不可能做你想做的事。Union是一种表示您的要求的方式。

现在要了解为什么要在 Julia 类型系统中观察到三个限制:

  1. 只有抽象类型可以有子类型。
  2. 一个类型只能有一个超类型。
  3. 定义类型时必须指定类型的超类型。

通过这种方式,我们知道类型创建了一个树状结构,根在哪里Any(除了Union{}没有值并且是所有其他类型的子类型,但实际上您可能不需要它)。

您的定义将违反规则#2 和规则#3。请注意,所有这些类型都已定义(在 Base 或包中) - 因此您无法重新定义它们(规则 #3)。他们也已经有一个超类型,所以你不能添加另一个(规则#2)。例如,请参阅此调用的结果:

julia> supertype(Array{Float64, 1})
DenseArray{Float64,1}

你会看到它Array{Float64, 1}已经定义并且有一个超类型。

话虽如此,也许另一个更一般的定义对您来说就足够了:

const FloatOrMissingVector = AbstractVector{<:Union{Float64, Missing}}

这个定义有两个不同之处:

  1. 它允许除密集向量之外的其他向量(我猜这是你想要的,因为通常你不关心向量是密集还是稀疏)
  2. 例如,它将允许Vector{Missing}作为子类型(因此是仅包含缺失值的结构)-如果您想排除这种情况,则必须按照上面的建议指定联合。

推荐阅读