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

Julia 类型

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

ASCIIString,Float64) 如果类型多元组中有非类型出现,会报错: julia> (1,"foo",2.5) :: (Int64,String,3) ERROR: type: typeassert: expected Type{T<:Top}, got (DataType,DataType,Int64) 注意,空多元组 () 的类型是其本身: julia> typeof(()) () 多元组类型是关于它的组成类型是协变的,一个多元组是另一个多元组的子类型意味着对应的第一个多元组的各元素的类型是第二个多元组对应元素类型的子类型。比如: julia> (Int,String) <: (Real,Any) true julia> (Int,String) <: (Real,Real) false julia> (Int,String) <: (Real,) false 直观地看,这就像一个函数的各个参数的类型必须是函数签名的子类型(当签名匹配的时候)。 类型共用体 类型共用体是特殊的抽象类型,使用 Union 函数来声明: julia> IntOrString = Union(Int,String) Union(String,Int64) julia> 1 :: IntOrString 1 julia> "Hello!" :: IntOrString "Hello!" julia> 1.0 :: IntOrString ERROR: type: typeassert: expected Union(String,Int64), got Float64 不含任何类型的类型共用体,是“底”类型 None : julia> Union() None 抽象类型 None 是所有其它类型的子类型,且没有实例。零参的 Union 调用,将返回无实例的类型 None 。 参数化类型 Julia 的类型系统支持参数化:类型可以引入参数,这样类型声明为每种可能的参数组合声明一个新类型。 所有被声明的类型(DataType 的变体)都可以使用同样的语法来参数化。我们将按照如下顺序来讨论:参数化符合类型、参数化抽象类型、参数化位类型。 参数化复合类型 abstract Pointy{T} type Point{T} <: Pointy{T} x::T y::T end 类型参数跟在类型名后,用花括号括起来: type Point{T} x::T y::T end 这个声明定义了新参数化类型 Point{T} ,它有两个 T 类型的“坐标轴”。参数化类型可以是任何类型(也可以是整数,此例中我们用的是类型)。具体类型 Point{Float64} 等价于将 Point 中的 T 替换为 Float64 后的类型。上例实际上声明了许多种类型:Point{Float64}, Point{String}, Point{Int64} 等等,因此,现在每个都是可以使用的具体类型: julia> Point{Float64} Point{Float64} (constructor with 1 method) julia> Point{String} Point{String} (constructor with 1 method) Point 本身也是个有效的类型对象: julia> Point Point{T} (constructor with 1 method) Point 在这儿是一个抽象类型,它包含所有如 Point{Float64}, Point{String} 之类的具体实例: julia> Point{Float64} <: Point true julia> Point{String} <: Point true 其它类型则不是其子类型: julia> Float64 <: Point false julia> String <: Point false Point 不同 T 值所声明的具体类型之间,不能互相作为子类型: julia> Point{Float64} <: Point{Int64} false julia> Point{Float64} <: Point{Real} false 这一点非常重要: 虽然 Float64 <: Real,但 Point{Float64} <: Point{Real} 不成立! 换句话说,Julia 的类型参数是 不相关 的。尽管 Point{Float64} 的实例按照概念来说,应该是 Point{Real} 的实例,但两者在内存中的表示上有区别: Point{Float64} 的实例可以简便、有效地表示 64 位数对儿 Point{Real} 的实例可以表示任意 Real 实例的数对儿。由于 Real 的实例可以为任意大小、任意结构,因此 Point{Real} 实际上表示指向 Real 对象的指针对儿 上述区别在数组中更明显: Array{Float64} 可以在一块连续内存中存储 64 位浮点数,而 Array{Real} 则保存指向每个 Real 对象的指针数组。而每个 Real 对象的大小,可能比 64 位浮点数的大。 构造函数中将介绍如何给复合类型自定义构造方法,但如果没有特殊构造声明时,默认有两种构造新复合对象的方法:一种是明确指明构造方法的类型参数;另一种是由对象构造方法的参数来隐含类型参数。 指明构造方法的类型参数: julia> Point{Float64}(1.0,2.0) Point{Float64}(1.0,2.0) julia> typeof(ans) Point{Float64} (constructor with 1 method) 参数个数应与构造函数相匹配: julia> Point{Float64}(1.0) ERROR: no method Point{Float64}(Float64) julia> Point{Float64}(1.0,2.0,3.0) ERROR: no method Point{Float64}(Float64, Float64, Float64) 对于带有类型参数的类型,因为重载构造函数是不可能的,所以只有一种默认构造函数被自动生成——这个构造函数接受任何参数并且把们转换成对应的字段类型并赋值 大多数情况下不需要提供 Point 对象的类型,它可由参数类型来提供信息。因此,可以不提供 T 的值: julia> Point(1.0,2.0) Point{Float64}(1.0,2.0) julia> typeof(ans) Point{Float64} (constructor with 1 method) julia> Point(1,2) Point{Int64}(1,2) julia> typeof(ans) Point{Int64} (constructor with 1 method) 上例中,Point 的两个参数类型相同,因此 T 可以省略。但当参数类型不同时,会报错: julia> Point(1,2.5) ERROR: `Point{T}` has no method matching Point{T}(::Int64, ::Float64) 这种情况其实也可以处理,详见构造函数。 参数化抽象类型 类似地,参数化抽象类型声明一个抽象类型的集合: abstract Pointy{T} 对每个类型或整数值 T,Pointy{T} 都是一个不同的抽象类型。Pointy 的每个实例都是它的子类型: julia> Pointy{Int64} <: Pointy true julia> Pointy{1} <: Pointy true 参数化抽象类型也是不相关的: julia> Pointy{Float64} <: Pointy{Real} false julia> Pointy{Real} <: Pointy{Float64} false 可以如下声明 Point{T} 是 Pointy{T} 的子类型: type Point{T} <: Pointy{T} x

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


Julia 类型