从零学Go(完结):内嵌和组合

这是我参与更文挑战的第 17 天,活动详情查看: 更文挑战

前文回顾

前面的文章主要介绍了 Go 语言中结构体和方法。结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。

接着结构体的讲解,本文将会介绍 Go 语言中内嵌和组合的使用。

内嵌和组合

在结构体定义时,Golang 允许声明没有字段名的字段,这种形式的字段被称为类型内嵌或者匿名字段,此时字段名就是字段类型本身,由于结构体要求字段名称必须唯一,因此同一类型的类型内嵌在同一结构体只能存在一个。如下例子所示:

type temp struct{
	string
	int
}
复制代码

如果内嵌的类型为结构体,就可以直接访问内嵌结构体中的所有成员,如下代码所示:

package main

import "fmt"

type Wheel struct {
	shape string
}

type Car struct {
	Wheel
	Name string
}

func main()  {

	car := &Car {
		Wheel {
			"圆形的",
		},
		"福特",
	}
	fmt.Println(car.Name, car.shape, " ") // 福特 圆形的
}

复制代码

在上述代码中,我们将 Wheel 结构体内嵌到 Car,就可以通过 Car 的引用直接访问到 Wheel 结构体中的成员属性。

使用结构体内嵌,可以很形象地模拟面向对象语言设计中组合的特性。结构体内嵌属于一种组合的特性,通过组合不同的基础结构体,可以构建出具备不同基础特性的复杂结构体。通过下面的例子我们来理解一下。

鸭子们既可以飞行,也可以游泳,但是并不是所有的鸭子都会两种行为,我们首先通过结构体定义这两种行为,代码如下所示:

// 游泳特性
type Swimming struct {
}

func (swim *Swimming) swim()  {
	fmt.Println("swimming is my ability")
}

// 飞行特性
type Flying struct {
}

func (fly *Flying) fly()  {
	fmt.Println("flying is my ability")
}
复制代码

其中野鸭既可以飞行,也可以游泳;而家鸭只会游泳。我们可以在它们之间分别内嵌不同的结构从而体现不同的行为:

// 野鸭,具备飞行和游泳特性
type WildDuck struct {
	Swimming
	Flying
}

// 家鸭,具备游泳特性
type DomesticDuck struct {
	Swimming
}
复制代码

最后在 main 函数中查看它们是否具备相对应的行为特性:

func main()  {
	// 声明一只野鸭,可以飞,也可以游泳
	wild := WildDuck{}
	wild.fly()
	wild.swim()

	// 声明一只家鸭,只会游泳
	domestic := DomesticDuck{}
	domestic.swim()
}
复制代码

从上述的例子可以看出,通过 Golang 的内嵌结构体特性可以实现对象的组合特性,为结构体添加各式各样的功能和特性,提高代码的可复用性和可扩展性。

小结

本文主要介绍了结构体的内嵌和组合特性。Go 语言中为了实现对象的组合特性,可以使用内嵌和组合,已实现为结构体添加各式各样的功能。

至此,Go 基础的语法知识已经讲解完。Go 是一门极具活力的新生代语言,它的设计就是为并发服务的,并集合了当前诸多优秀程序设计语言的优点,如自动垃圾回收、快速的静态类型检查、高性能等。在本系列文章,我们主要介绍了 Go 的基本语法和一些语言特性,包括原生数据类型、容器、函数、结构体等,使得你对 Go 语言的语法有基本的认知。通过这一系列文章的学习,我们已经具备基本 Go 开发能力。

下一系列文章,我将会进一步加深对 Go 语言的学习,更一步介绍 Go 中的包管理、反射和并发等高级特性,敬请期待

阅读最新文章,关注公众号:aoho求索