今天我们继续讨论关于 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,分三步完成:
-
使用
var teslaModelS = struct的语法; -
在大括号
{}内声明它的字段; -
使用结构体字面量(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 是匿名字段,我们可以直接访问其字段 City 和 State,就像它们属于 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 标签,还有其他类型的结构体标签可以使用。
总结
本节我们学习了结构体的高级使用方法,包括:
-
如何创建匿名结构体及其常见用途;
-
如何创建嵌套结构体以及访问嵌套字段;
-
匿名字段的使用及限制;
-
提升字段的概念及直接访问方式;
-
结构体标签及其在 JSON 编码中的应用。
通过这些知识,你就能更灵活、高效地使用 Go 的结构体了。
4万+

被折叠的 条评论
为什么被折叠?



