Go 结构体

结构体介绍

结构体是一种数据结构,通过实现复杂的结构来表示现实世界中的实体。结构体同时也是一些元素的集合,这些元素称为结构体的成员(又称字段),且这些成员可以为不同的类型,成员一般用名字访问。

结构体的声明一般是以 type 开始,并依次包含类型名称、关键字 struct 以及由花括号包裹的成员列表。

声明语句如下:

1
2
3
4
5
// Student 是一个表示学生的结构体
type Student struct {
Id int
Name string
}

其中,每个字段的声明都需要独占一行,且名字要唯一。如果字段在代码中从来也不会被用到,那么可以命名它为”_”。

带有标签的结构体

除了成员除了名称以及类型之外,还可以选择一个标签。标签是一个附属于字段的字符串,只有 reflect 可以操作它。

1
2
3
4
type Student struct {
Id int `json:"Id"`
Name string `json:"Name"`
}

使用 reflect 来获取其中的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import (
"fmt"
"reflect"
)

type Student struct {
Id int `json:"Id"` // 表明 Json 序列化时的名称。
Name string `json:"Name"`
}

func main() {
std := Student{1, "A"}

t := reflect.TypeOf(std)
for i := 0; i < 2; i++ {
ixField := t.Field(i)
fmt.Printf("%v\n", ixField.Tag)
}
// 输出
// json:"Id"
// json:"Name
}

结构体的初始化

  1. 使用 new 方法实例化一个结构体, 将会对该变量赋于一块内存,并返回指向内存的指针。
1
2
3
4
s := new(Student)
fmt.Println(s)
// output:
// &{0 }

使用 new(Type) 等价于 **&Type{}**,因为后者在底层调用了 new 方法。

除此之外,使用 var t T 也会给 t 分配内存,并零值化内存,但此时 t 的类型是 T,而不是指向它的一个指针。

  1. 使用工厂方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func NewStudent(id int, name string) *Student {
return &Student{
Id: id,
Name: name,
}
}

func main() {
s := NewStudent(1, "Apple")
size := unsafe.Sizeof(s) // 了解 s 所占用的内存
fmt.Println(s)
fmt.Println(size)
}

// output:
// &{1 Apple}
// 8

如果想要强制使用工厂方法,可以将类型设置为私有的,那么在其他包调用时只能使用工厂方法,而不能通过 new 方法来实例化。

值类型

与数组类型相同,结构体类型是值类型。结构体类型的零值并不是 nil。如之前的 Student 的零值就是 Student{0 }。

参考文献

  • 郝林. Go 并发编程实践(第二版). 人民邮电出版社(中文).
  • the-way-to-go_ZH_CN. “结构体的定义”.

Go 结构体
https://blog.zhangliangliang.cc/post/go-struct.html
作者
Bobby Zhang
发布于
2019年5月8日
许可协议