类型系统是指一个语言的类型体系结构。一个典型的类型系统通常包含如下基本内容:

  • 基础类型,如byte、 int、 bool、 float等;

  • 复合类型,如数组、结构体、指针等;

  • 可以指向任意对象的类型(Any类型);

  • 值语义和引用语义;

  • 面向对象,即所有具备面向对象特征(比如成员方法)的类型;

  • 接口

类型系统描述的是这些内容在一个语言中如何被关联。

为类型添加方法

在Go语言中,可以给任意类型(包括内置类型,但不包括指针类型)添加相应的方法,例如:
Go面向对象编程之系统类型 - 图1
在这个例子中,我们定义了一个新类型Integer,它和int没有本质不同,只是它为内置的int类型增加了个新方法Less()。

这样实现了Integer后,就可以让整型像一个普通的类一样使用:
Go面向对象编程之系统类型 - 图2

“在Go语言中没有隐藏的this指针”这句话的含义是:
方法施加的目标(也就是”对象”)显示传递,没有被隐藏起来;
方法施加的目标(也就是”对象”)不需要非得是指针,也不用非得叫this。

只有在你需要修改对象的时候,才必须用指针。它不是Go语言的约束,而是一种自然约束。

值语义和引用语义


值语义和引用语义的差别在于赋值,比如下面的例子:
b = a
b.Modify()

如果b的修改不会影响a的值,那么此类型属于值类型。如果会影响a的值,那么此类型是引用类型。

Go语言中的大多数类型都基于值语义,包括:

  • 基本类型,如byte、 int、 bool、 float32、 float64和string等;

  • 复合类型,如数组(array)、结构体(struct)和指针(pointer)等。

Go语言中类型的值语义表现得非常彻底。Go语言中的数组和基本类型没有区别,是很纯粹的值类型。

Go语言中有4个类型比较特别,看起来像引用类型,如下所示。

  • 数组切片:指向数组(array)的一个区间

Go面向对象编程之系统类型 - 图3

  • map:极其常见的数据结构,提供键值查询能力。

Go面向对象编程之系统类型 - 图4

  • channel:执行体(goroutine)间的通信设施。

Go面向对象编程之系统类型 - 图5

  • 接口(interface):对一组满足某个契约的类型的抽象。

Go面向对象编程之系统类型 - 图6
接口在Go语言中的地位非常重要。

结构体

Go语言的结构体(struct)和其他语言的类(class)有同等的地位,但Go语言放弃了包括继承在内的大量面向对象特性,只保留了组合(composition)这个最基础的特性。

组合甚至不能算面向对象特性,因为在C语言这样的过程式编程语言中,也有结构体,也有组合。组合只是形成复合类型的基础。

上面我们说到,所有的Go语言类型(指针类型除外)都可以有自己的方法。在这个背景下,Go语言的结构体只是很普通的复合类型,平淡无奇。例如,我们要定义一个矩形类型:

  1. type Rect struct {
  2. x, y float64
  3. width, height float64
  4. }

然后我们定义成员方法Area()来计算矩形的面积:

  1. func (r *Rect) Area() float64 {
  2. return r.width * r.height
  3. }

可以看出, Go语言中结构体的使用方式与C语言并没有明显不同。


Go面向对象编程之系统类型 - 图7