代码改变世界

Go 结构体高级用法 - 指南

2026-01-19 20:39  tlnshuju  阅读(0)  评论(0)    收藏  举报

今天我们继续讨论关于 struct(结构体) 的内容。在本主题中,你将学习结构体的高级使用概念:匿名结构体、嵌套结构体(即结构体中包含另一个或多个结构体作为字段)、匿名字段、提升字段以及 Go 中的结构体标签(struct tags)。


匿名结构体(Anonymous structs)

之前我们讲过基本的结构体类型声明,需要先创建一个新的数据类型。然而,我们也可以声明一个 不创建新数据类型的结构体,这种结构体称为 匿名结构体。看一个例子:

package main
import "fmt"
var teslaModelS = struct {
Brand, Model, Color string
weightInKg          int
}{
Brand:      "Tesla",
Model:      "Model S",
Color:      "Red",
weightInKg: 2250,
}
func main() {
fmt.Println(teslaModelS) // {Tesla Model S Red 2250}
}

代码解析
上面,我们声明了一个匿名结构体 teslaModelS,分三步完成:

  1. 使用 var teslaModelS = struct 的语法;

  2. 在大括号 {} 内声明它的字段;

  3. 使用结构体字面量(struct literal)初始化字段。

注意:匿名结构体必须立即附带一个结构体字面量初始化它的字段,否则编译器会报错,提示匿名结构体不是一个表达式。

作用

  • 匿名结构体提供了快速创建结构体而无需新建类型的方式。

  • 如果某个结构体只在程序中使用一次,使用匿名结构体能避免意外重复使用。

  • 匿名结构体常用于 表驱动的单元测试(table-driven unit tests)


嵌套结构体(Nested structs)

结构体可以组合不同的数据类型,所以一个结构体可以包含一个或多个结构体作为字段。来看一个例子:

type Address struct {
City  string
State string
}
type Employee struct {
Name    string
Age     int
Salary  float64
Address Address // 嵌套的 Address 结构体
}
func main() {
homer := Employee{
Name:    "Homer",
Age:     39,
Salary:  724.38,
Address: Address{City: "Springfield", State: "Oregon"},
}
fmt.Println("City:", homer.Address.City)   // City: Springfield
fmt.Println("State:", homer.Address.State) // State: Oregon
}

代码解析
Employee 结构体中声明了 Address 字段后,可以通过两次使用 . 操作符访问嵌套结构体的字段。


匿名字段(Anonymous fields)

结构体可以有只声明类型而不写字段名的字段,这种字段叫做 匿名字段。举个例子:

type Country struct {
string
int
}

代码解析

  • 虽然匿名字段没有字段名,但默认会以它的数据类型作为字段名。

  • 给匿名字段赋值:

var france Country
france.string = "France"
france.int = 67413000
fmt.Println("Country name:", france.string) // Country name: France
fmt.Println("Population:", france.int)      // Population: 67413000

注意

  • 一个数据类型只能有一个匿名字段,否则会报错,比如两个 string 类型匿名字段会出现重复字段错误。

提升字段(Promoted fields)

提升字段是指结构体中 匿名结构体字段的字段,我们可以直接通过外层结构体访问它们。例子:

package main
import "fmt"
type Address struct {
City string
State string
}
type Employee struct {
Name   string
Age    int
Salary float64
Address // 匿名字段,不写名字
}
func main() {
var homer Employee
homer.Name = "Homer"
homer.Age = 39
homer.Salary = 724.38
// 直接访问 Address 中的字段
homer.City = "Springfield"
homer.State = "Oregon"
fmt.Println("City:", homer.City)   // City: Springfield
fmt.Println("State:", homer.State) // State: Oregon
}

代码解析
由于 Address 是匿名字段,我们可以直接访问其字段 CityState,就像它们属于 Employee 结构体一样。


结构体标签(Struct tags)

Go 允许在结构体字段后添加 结构体标签(struct tags)。最常见的用途是控制 JSON 编码。例如,将以下 JSON 数据映射到 Go 结构体:

{
"userID": "123",
"isActive": true,
"lastLogin": "2021-12-08T11:27:32.834056-05:00",
"userType": 1
}

对应 Go 结构体:

type User struct {
UserID    string    `json:"userID"`
IsActive  bool      `json:"isActive"`
LastLogin time.Time `json:"lastLogin"`
UserType  int       `json:"userType"`
}

代码解析

  • 结构体标签必须用反引号 ` 包裹;

  • 标签格式为 key:"value",key 通常表示编码库(如 json);

  • value 表示对应的字段名,用于 JSON 编码或其他第三方库。

除了 JSON 标签,还有其他类型的结构体标签可以使用。


总结

本节我们学习了结构体的高级使用方法,包括:

  1. 如何创建匿名结构体及其常见用途;

  2. 如何创建嵌套结构体以及访问嵌套字段;

  3. 匿名字段的使用及限制;

  4. 提升字段的概念及直接访问方式;

  5. 结构体标签及其在 JSON 编码中的应用。

通过这些知识,你就能更灵活、高效地使用 Go 的结构体了。