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、Int64
及Int128
同是Signed的子类型,都是有符号整型;UInt8、UInt16、UInt32、UInt64
及UInt128
同是Unsigned的子类型,都是无符号整型;而Float16、Float32及Float64则是浮点型AbstractFloat的子类型。
如果将这些元类型及上节介绍的抽象类型之间的继承关系绘制出来,便能够获得更为完整的数值类型拓扑图,如图所示:
需要注意的是,在实际内存操作,一位作为独立的内存操作单元在机器指令中一般是不支持的。所以在定义元类型时,提供的位数值必须是8的倍数,即以字节为单位。上例中的布尔型是Integer的直接子类型,虽然理论上单比特就能够表达一个布尔值,例如1表示真,0表示假,但仍以8位定义了存储结构。
另外,虽然布尔型、Int8类型和UInt8在声明表述上一致,却并不能相互交换或替代,这是因为Julia采用的是主格(Nominative)类规则,而且它们有着不同的直接父类型:Bool的父类型是Integer, Int8的父类型是Signed,而UInt8的父类型则是Unsigned类型。
在实践中,如果要查询某个类型的父类型,可使用supertype()
函数,例如:
也可以使用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
但是,该函数只会列出给定类型的直接后继子类型,不会进行递归查询。
酷客网相关文章:
评论前必须登录!
注册