Julia语言程序设计
上QQ阅读APP看书,第一时间看更新

6.5.1 基本定义

Julia中,复合类型均通过struct关键字[1]进行声明,基本语法为:


[mutable] struct 类型名
  成员字段1::类型1
  成员字段2::类型2
  # 其他成员字段
end

其中,语法中的操作符::会限定成员字段为指定类型,不过是可以省略的。当省略时,成员类型默认为Any类型,意味着该字段变量能够绑定到任何已有的类型,包括元类型、抽象类型甚至是复合类型本身。关键字mutable是可选的标识符,不用时意味着该struct一旦实例化,成员取值将不能再进行任何变更;使用时则说明该struct可变,即创建后对象的成员可以反复被修改更新。

提示 如果了解其他面向对象语言会发现,struct内部并没有提供成员函数的定义语法,这是Julia有别于其他语言的特色之一:类型仅仅是类型。关键字struct仅需纯粹地声明复合类型,相关的各种操作方法可在结构外部进行定义,这也是Julia设计者建议的规范。

下面我们分别定义不可变和可变两个复合类型,如下:


struct FooA                              # 不可变类型
  a
  b::Float64
end

mutable struct FooB               # 可变类型
  a
  b::Float64
end

两者有着相同的字段,a无类型限制,b限定为Float64类型。

当然,成员也可以是复合类型,例如:


struct Bar
  m::FooB
  n::Int64
end

对于声明过的类型,我们可以通过内置的dump()函数查看其内部结构,如下:


FooA <: Any
  a::Any
  b::Float64

可见,a被默认为Any型,同时声明的复合类型的父类型也是Any型,因为复合类型也是Julia中的一种类型。另外一个复合类型FooB因类同不再列出。

不过,Bar的内部有些特别,如下:


Bar <: Any
  m::FooB
  n::Int64

其中,成员m是声明过的复合类型FooB。

实际上,如果查看声明的复合类型FooA本身的类型,会发现:


julia> typeof(FooA)
DataType

也是DataType的一种。事实上,以struct声明的复合类型均是DataType的实例对象。

对于声明的任意复合类型,除了使用dump()函数外,我们也可以通过一个专门函数fieldnames()获知其有哪些字段,例如:


julia> fieldnames(FooB)
(:a, :b)

该函数会在元组中以Symbol类型列出所有成员的名称。

[1] Julia在v0.6之前并没有struct,而是使用type定义复合类型,这是一个很大的变化。