Julia 的两个特殊类型

                     

贡献者: 待更新

   本文授权转载自郝林的 《Julia 编程基础》。原文链接:第 4 章 类型系统

4.3 两个特殊类型

   4.3.1 Any 类型

   在 Julia 的类型图中,Any 是一个唯一的顶层类型。如果说超类型在上、子类型在下的话,那么它就处在类型图的最顶端。Any 类型是所有类型的直接或间接的超类型。也就是说,对于任意类型的变量 x,类型断言 x::Any 都必定是成功的。

   还记得吗?我们在前面定义第一个 sum1 函数的时候,并没有为它的两个参数指定类型。然而,在这种情况下,这两个参数实际上都会有一个缺省的类型,即:Any 类型。这也是为什么我们可以用任何类型的值作为参数值调用这个 sum1 函数的原因。

   再比如,我们可以定义如下的原语类型(我们稍后会讲到这种类型):

julia> primitive type MyWord 64 end

julia>

   注意,我们没有显式地指定它的超类型。然而,在这种情况下,MyWord 类型会有一个缺省的超类型,同样是 Any 类型。也就是说,这个 MyWord 类型是 Any 类型的直接子类型。

   更宽泛地讲,Any 类型会在很多情况下担当默认类型并发挥其作用。我们在后面还会遇到类似的情形。另外,Any 类型是一个抽象类型。因此它本身是不能被实例化的。但所有的值却都是它的实例。

   4.3.2 Union 类型

   在 Julia 的类型图中,还有一个与 Any 完全相对的类型。它就是 Union{} 类型。由于这个类型是所有类型的子类型,所以它是一个底层类型,并且也是唯一的一个。它处在类型图的最底端。也就是说,对于任意类型的变量 x,类型断言 x::Union{} 都必定是失败的。另外,与 Any 一样,Union{} 也是一个抽象类型。

   从字面上我们就可以看出,Union{} 是一个被参数化的类型。它的源类型是 Union{Types...} 类型,其中的 Types... 代表任意个类型参数。如果这里有多个类型参数,那么它们之间需要用英文逗号分隔开。

   这个 Union{Types...} 类型有着一种很特殊的用途。我们可以利用它,让一个单一的类型字面量代表多个类型。换句话说,把多个类型联合在一起形成一个类型,并让后者作为前者的统一代表。因此,我们也可以把这个类型称为联合类型。而每一个类型参数的组合都可以代表一种联合类型。示例如下:

julia> IntOrString = Union{Integer, AbstractString} 
Union{AbstractString, Integer}

julia> 2020::IntOrString
2020

julia> "2020"::IntOrString
"2020"

julia>

   类型 Union{Integer, AbstractString} 表示的是 Integer 类型和 AbstractString 类型的联合。因此,任何 Integer 类型或 AbstractString 类型的实例都可以被视为这个联合类型的实例。这就是类型断言 2020::IntOrString"2020"::IntOrString 可以成功的原因。

   另外,由于 Julia 中的类型属于一类特殊的值(DataType 类型的值),所以上述的联合类型自然也就可以与标识符 IntOrString 绑定在一起。这时,我们可以说 IntOrString 是那个联合类型的别名(alias)。

   搞清楚了联合类型以及它的用途,我们就很容易理解 “Union{} 类型处在类型图的最底端” 的原因了。由于它的花括号中没有任何类型参数,所以这种联合类型也就代表不了任何类型,相当于一个 “虚无” 的类型。而任何类型都比 “虚无” 包含了更多的东西,所以它们都是这种联合类型的超类型。如果我们使用操作符 <: 在这些类型之间做判断的话,就可以很形象地看到这种关系:

julia> Union{} <: Integer
true

julia> Union{} <: Union{Integer}
true

julia>

   此示例中的两个表达式的结果值都是 true。这说明整数类型 Integer 和联合类型 Union{Integer} 都是 “虚无” 类型 Union{} 的超类型。

   至此,我们已经较为充分地了解了 Julia 类型图中的两端,即:最顶端的 Any 和最底端的 Union{}。下面,我们一起来看看在它们之间的类型都有哪些。

                     

© 小时科技 保留一切权利