当前位置:K88软件开发文章中心编程语言非主流编程语言Julia → 文章内容

Julia 类型

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-15 16:28:11

由 陈 创建,youj 最后一次修改 2016-08-12 类型 Julia 中,如果类型被省略,则值可以是任意类型。添加类型会显著提高性能和系统稳定性。 Julia 类型系统的特性是,具体类型不能作为具体类型的子类型,所有的具体类型都是最终的,它们可以拥有抽象类型作为父类型。其它高级特性有: 不区分对象和非对象值:Julia 中的所有值都是一个有类型的对象,这个类型属于一个单一、全连通类型图,图中的每个节点都是类型。 没有“编译时类型”:程序运行时仅有其实际类型,这在面向对象编程语言中被称为“运行时类型”。 值有类型,变量没有类型——变量仅仅是绑定了值的名字而已。 抽象类型和具体类型都可以被其它类型和值参数化。具体来讲, 参数化可以是 符号, 可以是 isbits 返回值为 true 的类型任意值 (本质想是讲, 这些数 像整数或者布尔值一样, 储存形式类似于 C 中的数据类型或者 struct, 并且 没有指向其他数据的指针), 也可以是元组。如果类型参数不需要被使用或者 限制, 可以省略不写。 Julia 的类型系统的设计旨在有效及具表现力,既清楚直观又不夸张。许多 Julia 程序员可能永远不会觉得有必要去明确地指出类型。然而某些程序会因声明类型变得更清晰,更简单,更迅速及健壮。 类型声明 :: 运算符可以用来在程序中给表达式和变量附加类型注释。这样做有两个理由: 作为断言,帮助确认程序是否正常运行 给编译器提供额外类型信息,帮助提升性能 :: 运算符放在表示值的表达式之后时读作“前者是后者的实例”,它用来断言左侧表达式是否为右侧表达式的实例。如果右侧是具体类型,此类型应该是左侧的实例。如果右侧是抽象类型,左侧应是一个具体类型的实例的值,该具体类型是这个抽象类型的子类型。如果类型断言为假,将抛出异常,否则,返回左值: julia> (1+2)::FloatingPoint ERROR: type: typeassert: expected FloatingPoint, got Int64 julia> (1+2)::Int 3 可以在任何表达式的所在位置做类型断言。 :: 最常见的用法是作为一个在函数/方法签名中的断言,例如 f(x::Int8) = ... (查看方法)。 :: 运算符跟在表达式上下文中的变量名后时,它声明变量应该是某个类型,有点儿类似于 C 等静态语言中的类型声明。赋给这个变量的值会被 convert 函数转换为所声明的类型: julia> function foo() x::Int8 = 1000 x end foo (generic function with 1 method) julia> foo() -24 julia> typeof(ans) Int8 这个特性用于避免性能陷阱,即给一个变量赋值时意外更改了类型。 “声明”仅发生在特定的上下文中: x::Int8 # a variable by itself local x::Int8 # in a local declaration x::Int8 = 10 # as the left-hand side of an assignment 并适用于整个当前范围,甚至在声明之前。目前,声明类型不能用于全局范围,例如在 REPL 中就不可以,因为 Julia 还没有定型的全局变量。需要注意的是在函数返回语句中,上述的前两个表达式计算值,还有就是 :: 是一个类型的断言不是一个声明。 抽象类型 抽象类型不能被实例化,它组织了类型等级关系,方便程序员编程。如,编程时可针对任意整数类型,而不需指明是哪种具体的整数类型。 使用 abstract 关键字声明抽象类型: abstract ?name? abstract ?name? <: ?supertype? abstract 关键字引入了新的抽象类型,类型名为 ?name? 。类型名后可跟 <: 及已存在的类型,表明新声明的抽象类型是这个“父”类型的子类型。 如果没有指明父类型,则父类型默认为 Any ——所有对象和类型都是这个抽象类型的子类型。在类型理论中,Any 位于类型图的顶峰,被称为“顶”。Julia 也有预定义的抽象“底”类型,它位于类型图的最底处,被称为 None。None与 Any 对立:任何对象都不是 None 的实例,所有的类型都是 None 的父类型。 下面是构造 Julia 数值体系的抽象类型子集的具体例子: abstract Number abstract Real <: Number abstract FloatingPoint <: Real abstract Integer <: Real abstract Signed <: Integer abstract Unsigned <: Integer <: 运算符意思为“前者是后者的子类型”,它声明右侧是左侧新声明类型的直接父类型。也可以用来判断左侧是不是右侧的子类型: julia> Integer <: Number true julia> Integer <: FloatingPoint false 抽象类型的一个重要用途是为具体的类型提供默认实现。举个简单的例子: function myplus(x, y) x + y endof 第一点需要注意的是, 上面的参数声明等效于 x::Any 和 y::Any. 当这个函数被调用时, 例如 myplus(2, 5), Julia 会首先查找参数类型匹配的 myplus 函数. (关于多重分派的详细信息请参考下文.) 如果没有找到比上面的函数更相关的函数, Julia 根据上面的通用函数定义并编译一个 myplus 具体函数, 其参数为两个 Int 型变量, 也就是说, Julia 会定义并编译: function myplus(x::Int, y::Int) x + y end 最后, 调用这个具体的函数。 因此, 程序员可以利用抽象类型编写通用的函数,然后这个通用函数可以被许多具体的类型组合调用。也正是由于多重分派,程序员可以精确的控制是调用更具体的还是通用的函数。 需要注意的一点是, 编写面向抽象类型的函数并不会带来性能上的损失,因为每次调用函数时,根据不同的参数组合,函数总是要重新编译的。(然而, 如果参数类型为包含抽象类型的容器是, 会有性能方面的问题;参见下面的关于性能的提示。) 位类型 位类型是具体类型,它的数据是由位构成的。整数和浮点数都是位类型。标准的位类型是用 Julia 语言本身定义的: bitstype 16 Float16 <: FloatingPoint bitstype 32 Float32 <: FloatingPoint bitstype 64 Float64 <: FloatingPoint bitstype 8 Bool <: Integer bitstype 32 Char <: Integer bitstype 8 Int8 <: Signed bitstype 8 Uint8 <: Unsigned bitstype 16 Int16 <: Signed bitstype 16 Uint16 <: Unsigned bitstype

[1] [2] [3] [4]  下一页


Julia 类型