从零学Go:结构体和方法

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

前文回顾

前面的文章主要介绍了 Go 语言中函数和接口相关的使用实践。与 C 语言类似,Golang 提供结构体类型。结构体作为一种复合类型,由多个字段组成,每个字段都具备自己的类型和值,结构体和字段可以理解为实体和实体对应的属性。在 Golang 中,不仅结构体可以拥有方法,每一种自定义类型都可以拥有方法。

本文将会开始介绍结构体和方法。结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。首先了解下结构体的定义。

结构体的定义

配合使用typestruct关键字,可以自定义结构体。Golang 的 type 关键字可以将各种基本类型定义为自定义类型,结构体中可以复合多种基本类型和结构体,更便于使用。结构体的定义样式如下所示:

type structName struct{
	value1 valueType1
	value2 valueType2
	...
}
复制代码

结构体的名称在同一个包内不能重复,如果希望结构体在包外也能够被访问,结构体的首字母需要大小。结构体中字段名必须唯一,如果字段是公开的,字段名的首字母同样需要大写。

我们尝试定义一个简单的结构体 Person,它具备姓名、生日、身份证号等字段,代码如下所示:

type Person struct {
	Name string	// 姓名
	Birth string	// 生日
	ID int64	// 身份证号
}
复制代码

结构体的实例化和初始化

实例化将为结构体分配具体的内存用于存储字段,结构体必须在实例化之后才能够使用。实例化会根据结构体的定义为结构体在内存中创建一份样式一致的内存区域用于存储结构体,每个结构体实例之间的内存区域是相互独立的。

实例化结构体的方式有很多,比如说我们可以直接像声明基本类型一样实例化结构体,实例化之后可以对其字段进行赋值,以上一小节中定义的 Person 结构体为例,如下所示:

// 声明实例化
var p1 Person
p1.Name =  "王小二"
p1.Birth = "1990-12-11"
复制代码

也可以使用 new 函数为结构体申请对应的内存区域,这将返回结构体对应的指针类型,之后我们同样可以使用 . 对结构体的字段进行赋值,代码如下所示:

// new 函数实例化
p2 := new(Person)
p2.Name = "王二小"
p2.Birth = "1990-12-22"
复制代码

除此之外,还有使用 & 对结构体进行取址,这将被视为使用了一次 new 实例化操作,同样将返回指针类型,代码如下所示:

// 取址实例化
p3 := &Person{}
p3.Name = "王三小"
p3.Birth = "1990-12-23"
复制代码

在结构体实例化的过程中,我们就可以对结构体内的字段进行初始化,使用类似 JSON 的键值对表示方式可以对结构体的字段进行填充。字段的初始化是可选的。依然使用 Person 结构体作为例子,代码如下所示:

// 初始化
p4 := Person{
	Name:"王小四",
	Birth: "1990-12-23",
}
复制代码

当结构体内的所有字段都需要初始化,并且字段的填充顺序与它们在结构体内定义的顺序一致时,可以将键值对中的键省略,如下所示:

// 初始化
p5 := &Person{
	"王五",
	"1990-12-23",
	5,
}
复制代码

上述例子使用的是取址实例化,返回的 p5 类型为 Person 结构体的指针类型,即 *Person

小结

本文主要介绍了结构体的定义以及结构体的实例化和初始化。Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。结构体作为一种复合类型,由多个字段组成,每个字段都具备自己的类型和值,结构体和字段可以理解为实体和实体对应的属性。