美文网首页
JULIA-类型

JULIA-类型

作者: 9016 | 来源:发表于2018-11-14 08:40 被阅读107次

类型操作

断言运算符::
::,作为运算符时语法:
左表达式::右数据类型,判断“左表达式”是否为“右数据类型”的实例,如果true,返回“左表达式”的值,如果false,返回错误信息。
true情况,例如

julia> (9.0*9.0) :: Float64
81.0

julia> (9*9) :: Int
81

julia> (9*9) :: Int64
81

julia> (9.0*9.0) :: Float64
81.0

julia> ("A") :: String
"A"

false情况,例如:

julia> (9*9) :: String
ERROR: TypeError: in typeassert, expected String, got Int64
Stacktrace:
 [1] top-level scope at none:0

::在local变量时的使用
在代码块中赋值变量时,可以使用::做变量类型声明,语法:
变量名::类型 = 值
变量在赋值的同时声明类型,例如:

julia> function f_local()
          x :: String = "this is function local string"
          x
        end
f_local (generic function with 1 method)

julia> f_local()
"this is function local string"

julia> typeof(ans)
String

对于返回值的类型,可以在函数定义时做出声明,例如上面f_local()这个函数还可以这样写:

julia> function f_local() :: String
x = "this is function local string"
x
end
f_local (generic function with 1 method)

julia> f_local()
"this is function local string"

julia> typeof(ans)
String

当在function之外,非local类型是,这样写是不符合语法的,错误信息中明确提示了,global类型是不能这么做类型声明的,例如:

julia>  x :: String = "this is function local string"
ERROR: syntax: type declarations on global variables are not yet supported

上面这句,在特定条件下,可以写成local类型,例如:

julia> local x :: String = "this is function local string"
"this is function local string"

isa 函数
测试对象是否具有给定类型并返回 true 或 false:

julia> isa(123,Int64)
true

julia> isa(123,Float64)
false

typeof函数
返回其参数的类型:

julia> typeof(Float64)
DataType

julia> primitive type Ptr{T} 64 end

julia> typeof(Ptr)
UnionAll

julia> typeof(UnionAll)
DataType

supertype函数
返回类型的父类型:

julia> supertype(Int64)
Signed

julia> supertype(Float64)
AbstractFloat

julia> supertype(Any)
Any

抽象类型

抽象类型不能实例化,但它们是类型系统的主干。
Int8、UInt8、Int16、UInt16、Int32、UInt32、Int64、UInt64、Int128、UInt128、Float16、Float32 和 Float64,这些类型都不是抽象类型,它们是后面我们要介绍的原始类型。
声明抽象类型的语法:

abstract type «name» end
abstract type «name» <: «supertype» end

第一句没有“<: «supertype»”,系统默认它的父类型Any。
Julia系统内置抽象类型:
Number,Number下有Real,Real下有AbstractFloat和Integer,Integer下有Signed和Unsigned。
<: 运算符的通常意义为「是···的子类型」:

julia> Unsigned <: Number
true

julia> Unsigned <: Real
true

julia> Unsigned <: Integer
true

抽象类型允许程序员编写范型函数,之后可以通过许多具体类型将其用作对应的方法。

julia> mp(x,y) = x+y
mp (generic function with 1 method)

julia> mp(1,2)
3

julia> mp(1.1,2.2)
3.3000000000000003

原始类型

抽象类型可以实例化,Julia 允许声明自己的原始类型,且内置了大量的原始类型Int8、UInt8、Int16、UInt16、Int32、UInt32、Int64、UInt64、Int128、UInt128、Float16、Float32 和 Float64…………
声明抽象类型的语法:

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

bits 的数值表示该类型需要多少存储空间,name 为新类型指定名称。
第一句没有“<: «supertype»”,系统默认它的父类型Any。

Julia类型的层级关系

Julia内部的数据类型按照层级分布,某些数据类型位于其他数据类型之上。
subtypes()返回作为参数传递的类型的子类型函数。

julia> function check_all_subtypes(T, space = 0)
println("\t" ^ space, T)
for t in subtypes(T)
if t != Any
check_all_subtypes(t, space+1)
end
end
end
check_all_subtypes (generic function with 2 methods)

julia> check_all_subtypes(Number)
Number
        Complex
        Real
                AbstractFloat
                        BigFloat
                        Float16
                        Float32
                        Float64
                AbstractIrrational
                        Irrational
                Integer
                        Bool
                        Signed
                                BigInt
                                Int128
                                Int16
                                Int32
                                Int64
                                Int8
                        Unsigned
                                UInt128
                                UInt16
                                UInt32
                                UInt64
                                UInt8
                Rational

julia> check_all_subtypes(AbstractString)
AbstractString
        String
        SubString
        SubstitutionString
        Test.GenericString

复合类型

复合类型是变量名域的集合。下例中,使用struct关键字,快速定义复合类型Person:

julia> struct Person
name::String
age::Int64
end

julia> Jack = Person("Jack",27)
Person("Jack", 27)

julia> typeof(Jack)
Person

julia> Jack.name
"Jack"

julia> Jack.age
27

可变复合类型

上面的复合类型的实例Jack,如果对Jack的名字做更改叫“Rose”:

julia> Jack.name = "Rose"
ERROR: type Person is immutable
Stacktrace:
 [1] setproperty!(::Person, ::Symbol, ::String) at .\sysimg.jl:19
 [2] top-level scope at none:0

有时有这样的需求,要求对对象的某个属性进行调整,这就引入了可变复合类型,关键字mutable。

julia> mutable struct Employee
name::String
age::Int64
end

julia> Boss = Employee("Jack",35)
Employee("Jack", 35)

julia> Boss.name = "Rose"
"Rose"

类型共用体

类型共同体内定义的类型,简单地理解,比Any少,比具体的原始类型又要多。这里的关键字是Union,不是Struct。
下面的点定义了类型共同体TypeMemo,只接受字符或字符串。当使用Int64类型与TypeMemo做匹配断言时,报错:

julia> TypeMemo = Union{Char, String}
Union{Char, String}

julia> "a" :: TypeMemo
"a"

julia> "abc" :: TypeMemo
"abc"

julia> 123 :: TypeMemo
ERROR: TypeError: in typeassert, expected Union{Char, String}, got Int64
Stacktrace:
 [1] top-level scope at none:0

参数类型

类型可以接受参数,每一个参数值的可能组合引入一个新类型。

参数复合类型

下面代码定义了参数复合类型Point,在这里参数有两个x、y,为入参类型(泛型):

julia> struct Point{}
x::T
y::T
end

因为Point作为一个类型,下面每一个Point{T}都是它的子类型,所以:

julia> Point{Float64} <: Point
true

julia> Point{Int64} <: Point
true

julia> Point{String} <: Point
true

julia> Point{Char} <: Point
true

尽管Point的入参为Any类型,但是其他原始类型并非Point的子类型:

julia> Float64 <: Point
false

julia> Int64 <: Point
false

julia> String <: Point
false

julia> Char <: Point
false

Point下各个子类型相互间也没有层级关系:

julia> Point{Int64} <: Point{Real}
false

julia> Point{Float64} <: Point{Real}
false

julia> Point{String} <: Point{Any}
false

参数复合类型Point的实例化和引用格式:

julia> struct Point{T1,T2}
x::T1
y::T2
end

julia> function product(p::Point{<: Float64})
p.x * p.y
end
fc (generic function with 1 method)

julia> product(Point(1.1,2.2))
2.4200000000000004

接上面的代码,如果复合类型在引用时Point{Real}格式,将不包含Float64类型,所以:

julia> function product1(p::Point{Real})
p.x * p.y
end
fc (generic function with 1 method)

julia> product1(Point(1.1,2.2))
ERROR: MethodError: no method matching no(::Point{Float64,Float64})
Closest candidates are:
  no(::Point{Real,T2} where T2) at none:2

为了包括包含Float64类型,使用<:运算符

julia> function product2(p::Point{<:Real})
p.x * p.y
end
fc (generic function with 1 method)
julia> product1(Point(1.1,2.2))

julia> product2(Point(1.1,2.2))
2.4200000000000004

复合类型Point,可以按照构造函数的形式,定义T1、T2的类型:

julia> Point(1,2)
Point{Int64,Int64}(1, 2)

julia> Point(1.2,2.3)
Point{Float64,Float64}(1.2, 2.3)

julia> Point(1.2,2)
Point{Float64,Int64}(1.2, 2)

😎参数复合类型定义可以使用mutable关键字,具体用法可以参考可变复合类型章节。

元组类型

元组和数组很像。
开数组并推数:
data =[]
push!(data,111)
push!(data,"222")
push!(data,333.33)

julia> println(data)
Any[111, "222", 333.33]

julia> typeof(data)
Array{Any,1}

julia> data[1] = 7788
7788

定义元组:
a = (111,"222",333.33)

julia> println(a)
(111, "222", 333.33)

julia> typeof(a)
Tuple{Int64,String,Float64}

julia> a[1] = 7788
ERROR: MethodError: no method matching setindex!(::Tuple{Int64,String,Float64},
::Int64, ::Int64)

😎从上例可以看出,数组和元组相似,同一数组或者元组内元素类型可以各不相同,下标都是从1开始,不同点在于数组可以通过下标访问并重新赋值,元组可以通过下标访问,但是不能重新赋值。

变参元组类型

关键字Tuple、Vararg,表示该类型元素数量不定。

julia> mulittuple = Tuple{String,Vararg{Int}}
Tuple{String,Vararg{Int64,N} where N}

julia> isa(("1",),mulittuple)
true

julia> isa(("1",123),mulittuple)
true

julia> isa(("1",123,2,3,4,5,6),mulittuple)
true

julia> isa(("1",123,2,3,4,5,6,7.7),mulittuple)
false

具名元组类型

就是带参数名的元组。
下面元组实例时的a\b\c就是参数名。

julia> x = (a=1,b=2.2,c="abc")
(a = 1, b = 2.2, c = "abc")

julia> typeof(x)
NamedTuple{(:a, :b, :c),Tuple{Int64,Float64,String}}

单态类型

简单地说,Type(T)的实例就是T。

julia> isa(Float64,Type{Float64})
true

julia> isa(Float64,Type{Real})
false

又因为,Type不带参数时,所有类型对象都是它的实例,当然也包括单态类型:

julia> isa(Float64,Type)
true

julia> isa(String,Type)
true

参数化原始类型

primitive type 为关键字,T为类型参数,例如在64位操作系统,可以声明:
primitive type Ptr{T} 64 end
不同的T表示不同的Ptr类型,尽管都叫Ptr,但是不同类型间无父子关系,所以:

julia> primitive type Ptr{T} 64 end

julia> Ptr{Int64} <: Ptr
true

julia> Ptr{Real} <: Ptr
true

julia> Ptr{Signed} <: Ptr
true

julia> Ptr{Int64} <: Ptr{Signed}
false

julia> Ptr{Int64} <: Ptr{Real}
false

julia> Ptr{Signed} <: Ptr{Real}
false

primitive type类型可以理解为C里的指针,Ptr{Int64}近似于int*,Ptr{Float64}近似于double*。

类型的别名

类型可以定义别名,通过1.0版本中,通过const关键字实现:

julia> const myint = Int64
Int64

julia> myint
Int64

在这里,myint是Int64的别名。

typeof 获得类型
supertype获得某个类型的父类型
eltype获得某个数集的元素类型

相关文章

  • JULIA-类型

    类型操作 断言运算符::::,作为运算符时语法:左表达式::右数据类型,判断“左表达式”是否为“右数据类型”的实例...

  • JULIA-函数

    函数就是f(x,y,...),f(x,y,...)就是函数。学过高中数学的都知道。 函数的基本结构: Julia里...

  • JULIA-值域

    值域,变量的作用域。是变量有效区域,每一种高级语言,都会对变量作用域做出定义,以规范变量命名规则,避免变量命名引起...

  • Julia-简单教程

    相关网站 https://julialang.org/ julia 官网 https://github.com/J...

  • JULIA-控制流

    复合表达式 有时,使用一组表达式按顺序计算几个子表达式,将最后一个子表达式的值作为其值返回。这一组表达式叫做复合表...

  • JULIA-如何开辟动态数组

    很多时候,我们在声明数组时不知道数组长度。这对其他语言不是难事,但对julia,有特殊函数push!()解决此问题...

  • julia-概率-统计-相关的包

    资料来源,昆士兰大学的《Statistics With Julia》中文翻译为机器翻译,大家注意斟别。 Calcu...

  • julia-计算文本文件行数

    Julia内置的很多函数很方便,比如计算文本文件的行数,在linux 用wc -l 命令就可与完成,但是有时文件是...

  • JULIA-为了我们的美好回忆-Hello world!

    对于初学者而言,Hello world!是必写的一个程序。 无论是JAVA,还是曾经辉煌的PHP、C++,Hell...

  • JULIA-为了我们的美好回忆-冒泡排序!

    本来想写个乘法口诀表,想想无非就是打印九九八十一次,显得没技术含量。忽然想起道友前一阵写的冒泡,凭印象练了一下手,...

网友评论

      本文标题:JULIA-类型

      本文链接:https://www.haomeiwen.com/subject/ptrsxqtx.html