Julia元类型

Julia元类型

如果我们试图以上述的抽象类型创建对象,会发现:

julia> Integer(10)
10

julia> typeof(ans)
Int64

julia> AbstractFloat(10)
10.0

julia> typeof(ans)
Float64

其中,虽然Integer定义整数值10,但实际归属在具体类型Int64下;AbstractFloat的情况同样如此。原因如前所述,抽象类型是无法实例化的,因为其并没有存储结构方面的定义。若要存储这些真实的数值,只能转为其子类型中的某个具体类型(这个过程会由Julia自动执行)。

所谓“元类型”,是具体类型的一种,不但有明确的二进制内存结构,也是构成其他数据的基础。简单来说,元类型是概念单一、结构纯粹的基本类型,其数据在内存中是连续的位序列。

所以在Julia中基于关键字primitive type声明一个元类型时,需要给出明确的位数:

primitive type name bits end
primitive type name <: supertype bits end

其中除了告知待声明元类型的名字name外,还需使用bits告知表达该类型时需要的位数,即该类型在容纳数据时的内存结构。

同抽象类型类似,在声明元类型时也可以同时给出其父类型。例如:

primitive type Float16 <: AbstractFloat 16 end

其中,声明了名为Float16的元类型,是浮点型AbstractFloat的一种,用16位表达浮点数。

实际上,酷客教程介绍的各种整型浮点型等数字类型都是元类型的一种,都有着对应的元类型声明语句,如下所示:

primitive type Float16  <: AbstractFloat 16 end
primitive type Float32  <: AbstractFloat 32 end
primitive type Float64  <: AbstractFloat 64 end
primitive type Bool      <: Integer         8 end
primitive type Char      <: AbstractChar  32 end
primitive type Int8      <: Signed           8 end
primitive type UInt8     <: Unsigned        8 end
primitive type Int16     <: Signed         16 end
primitive type UInt16    <: Unsigned       16 end
primitive type Int32     <: Signed         32 end
primitive type UInt32    <: Unsigned       32 end
primitive type Int64     <: Signed         64 end
primitive type UInt64    <: Unsigned       64 end
primitive type Int128    <: Signed        128 end
primitive type UInt128  <: Unsigned      128 end

其中,Int8、Int16、Int32、Int64Int128同是Signed的子类型,都是有符号整型;UInt8、UInt16、UInt32、UInt64UInt128同是Unsigned的子类型,都是无符号整型;而Float16、Float32及Float64则是浮点型AbstractFloat的子类型。

如果将这些元类型及上节介绍的抽象类型之间的继承关系绘制出来,便能够获得更为完整的数值类型拓扑图,如图所示:
Julia元类型

需要注意的是,在实际内存操作,一位作为独立的内存操作单元在机器指令中一般是不支持的。所以在定义元类型时,提供的位数值必须是8的倍数,即以字节为单位。上例中的布尔型是Integer的直接子类型,虽然理论上单比特就能够表达一个布尔值,例如1表示真,0表示假,但仍以8位定义了存储结构。

另外,虽然布尔型、Int8类型和UInt8在声明表述上一致,却并不能相互交换或替代,这是因为Julia采用的是主格(Nominative)类规则,而且它们有着不同的直接父类型:Bool的父类型是Integer, Int8的父类型是Signed,而UInt8的父类型则是Unsigned类型。

在实践中,如果要查询某个类型的父类型,可使用supertype()函数,例如:
Julia元类型

也可以使用subtypes()获得某个类型的子类型列表,例如:

julia> subtypes(Signed)
5-element Array{Union{DataType, UnionAll},1}:
  Int128
  Int16
  Int32
  Int64
  Int8

julia> subtypes(Real)
4-element Array{Any,1}:
  AbstractFloat
  AbstractIrrational
  Integer
  Rational

但是,该函数只会列出给定类型的直接后继子类型,不会进行递归查询。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!