892 lines
21 KiB
Go
892 lines
21 KiB
Go
/*
|
||
04-structs.go - Go 语言结构体详解
|
||
|
||
学习目标:
|
||
1. 理解结构体的概念和作用
|
||
2. 掌握结构体的定义和使用
|
||
3. 学会结构体的初始化方式
|
||
4. 了解结构体的嵌入和组合
|
||
5. 掌握结构体的实际应用场景
|
||
|
||
知识点:
|
||
- 结构体的定义和特性
|
||
- 结构体的初始化方式
|
||
- 结构体字段的访问和修改
|
||
- 结构体的方法
|
||
- 结构体的嵌入和组合
|
||
- 结构体的标签
|
||
- 结构体的比较和拷贝
|
||
*/
|
||
|
||
package main
|
||
|
||
import (
|
||
"fmt"
|
||
)
|
||
|
||
func main() {
|
||
fmt.Println("=== Go 语言结构体详解 ===\n")
|
||
|
||
// 演示结构体的基本概念
|
||
demonstrateBasicStructs()
|
||
|
||
// 演示结构体的初始化
|
||
demonstrateStructInitialization()
|
||
|
||
// 演示结构体的方法
|
||
demonstrateStructMethods()
|
||
|
||
// 演示结构体的嵌入
|
||
demonstrateStructEmbedding()
|
||
|
||
// 演示结构体的标签
|
||
demonstrateStructTags()
|
||
|
||
// 演示结构体的高级特性
|
||
demonstrateAdvancedStructFeatures()
|
||
|
||
// 演示结构体的实际应用
|
||
demonstratePracticalApplications()
|
||
}
|
||
|
||
// demonstrateBasicStructs 演示结构体的基本概念
|
||
func demonstrateBasicStructs() {
|
||
fmt.Println("1. 结构体的基本概念:")
|
||
|
||
// 结构体的基本特性
|
||
fmt.Printf(" 结构体的基本特性:\n")
|
||
fmt.Printf(" - 用户自定义的复合数据类型\n")
|
||
fmt.Printf(" - 将相关数据组织在一起\n")
|
||
fmt.Printf(" - 值类型,赋值和传参会拷贝\n")
|
||
fmt.Printf(" - 可以有方法\n")
|
||
fmt.Printf(" - 支持嵌入和组合\n")
|
||
|
||
// 基本结构体示例
|
||
fmt.Printf(" 基本结构体示例:\n")
|
||
|
||
// 创建结构体实例
|
||
var p Person
|
||
fmt.Printf(" 零值结构体: %+v\n", p)
|
||
|
||
// 设置字段值
|
||
p.Name = "Alice"
|
||
p.Age = 25
|
||
p.Email = "alice@example.com"
|
||
fmt.Printf(" 设置字段后: %+v\n", p)
|
||
|
||
// 访问字段
|
||
fmt.Printf(" 姓名: %s\n", p.Name)
|
||
fmt.Printf(" 年龄: %d\n", p.Age)
|
||
fmt.Printf(" 邮箱: %s\n", p.Email)
|
||
|
||
// 结构体比较
|
||
fmt.Printf(" 结构体比较:\n")
|
||
p1 := Person{Name: "Bob", Age: 30, Email: "bob@example.com"}
|
||
p2 := Person{Name: "Bob", Age: 30, Email: "bob@example.com"}
|
||
p3 := Person{Name: "Charlie", Age: 25, Email: "charlie@example.com"}
|
||
|
||
fmt.Printf(" p1 == p2: %t\n", p1 == p2)
|
||
fmt.Printf(" p1 == p3: %t\n", p1 == p3)
|
||
|
||
// 结构体作为值类型
|
||
fmt.Printf(" 结构体作为值类型:\n")
|
||
original := Person{Name: "David", Age: 35, Email: "david@example.com"}
|
||
copied := original
|
||
|
||
fmt.Printf(" 原结构体: %+v\n", original)
|
||
fmt.Printf(" 拷贝结构体: %+v\n", copied)
|
||
|
||
// 修改拷贝不影响原结构体
|
||
copied.Age = 40
|
||
fmt.Printf(" 修改拷贝后:\n")
|
||
fmt.Printf(" 原结构体: %+v\n", original)
|
||
fmt.Printf(" 拷贝结构体: %+v\n", copied)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateStructInitialization 演示结构体的初始化
|
||
func demonstrateStructInitialization() {
|
||
fmt.Println("2. 结构体的初始化:")
|
||
|
||
// 方式1: 零值初始化
|
||
fmt.Printf(" 方式1 - 零值初始化:\n")
|
||
var p1 Person
|
||
fmt.Printf(" var p1 Person: %+v\n", p1)
|
||
|
||
// 方式2: 字段名初始化
|
||
fmt.Printf(" 方式2 - 字段名初始化:\n")
|
||
p2 := Person{
|
||
Name: "Alice",
|
||
Age: 25,
|
||
Email: "alice@example.com",
|
||
}
|
||
fmt.Printf(" 字段名初始化: %+v\n", p2)
|
||
|
||
// 方式3: 位置初始化(不推荐)
|
||
fmt.Printf(" 方式3 - 位置初始化:\n")
|
||
p3 := Person{"Bob", 30, "bob@example.com"}
|
||
fmt.Printf(" 位置初始化: %+v\n", p3)
|
||
|
||
// 方式4: 部分初始化
|
||
fmt.Printf(" 方式4 - 部分初始化:\n")
|
||
p4 := Person{
|
||
Name: "Charlie",
|
||
Age: 35,
|
||
// Email 使用零值
|
||
}
|
||
fmt.Printf(" 部分初始化: %+v\n", p4)
|
||
|
||
// 方式5: 使用 new 函数
|
||
fmt.Printf(" 方式5 - 使用 new 函数:\n")
|
||
p5 := new(Person)
|
||
p5.Name = "David"
|
||
p5.Age = 40
|
||
fmt.Printf(" new(Person): %+v\n", *p5)
|
||
|
||
// 方式6: 结构体字面量的地址
|
||
fmt.Printf(" 方式6 - 结构体字面量的地址:\n")
|
||
p6 := &Person{
|
||
Name: "Eve",
|
||
Age: 28,
|
||
Email: "eve@example.com",
|
||
}
|
||
fmt.Printf(" &Person{...}: %+v\n", *p6)
|
||
|
||
// 复杂结构体初始化
|
||
fmt.Printf(" 复杂结构体初始化:\n")
|
||
|
||
addr := Address{
|
||
Street: "123 Main St",
|
||
City: "New York",
|
||
Country: "USA",
|
||
ZipCode: "10001",
|
||
}
|
||
|
||
employee := Employee{
|
||
Person: Person{
|
||
Name: "Frank",
|
||
Age: 32,
|
||
Email: "frank@company.com",
|
||
},
|
||
ID: 1001,
|
||
Position: "Software Engineer",
|
||
Salary: 75000,
|
||
Address: addr,
|
||
}
|
||
|
||
fmt.Printf(" 复杂结构体: %+v\n", employee)
|
||
|
||
// 匿名结构体
|
||
fmt.Printf(" 匿名结构体:\n")
|
||
point := struct {
|
||
X, Y int
|
||
}{
|
||
X: 10,
|
||
Y: 20,
|
||
}
|
||
fmt.Printf(" 匿名结构体: %+v\n", point)
|
||
|
||
fmt.Println()
|
||
}//
|
||
demonstrateStructMethods 演示结构体的方法
|
||
func demonstrateStructMethods() {
|
||
fmt.Println("3. 结构体的方法:")
|
||
|
||
// 创建结构体实例
|
||
fmt.Printf(" 结构体方法调用:\n")
|
||
|
||
rect := Rectangle{Width: 10, Height: 5}
|
||
fmt.Printf(" 矩形: %+v\n", rect)
|
||
fmt.Printf(" 面积: %.2f\n", rect.Area())
|
||
fmt.Printf(" 周长: %.2f\n", rect.Perimeter())
|
||
|
||
// 值接收者 vs 指针接收者
|
||
fmt.Printf(" 值接收者 vs 指针接收者:\n")
|
||
|
||
// 值接收者方法
|
||
fmt.Printf(" 调用值接收者方法:\n")
|
||
info := rect.String()
|
||
fmt.Printf(" String(): %s\n", info)
|
||
|
||
// 指针接收者方法
|
||
fmt.Printf(" 调用指针接收者方法:\n")
|
||
fmt.Printf(" 修改前: %+v\n", rect)
|
||
rect.Scale(2.0)
|
||
fmt.Printf(" Scale(2.0)后: %+v\n", rect)
|
||
|
||
// 方法链调用
|
||
fmt.Printf(" 方法链调用:\n")
|
||
rect2 := Rectangle{Width: 3, Height: 4}
|
||
fmt.Printf(" 原矩形: %+v\n", rect2)
|
||
|
||
result := rect2.SetWidth(6).SetHeight(8)
|
||
fmt.Printf(" 链式调用后: %+v\n", *result)
|
||
|
||
// 结构体方法作为函数值
|
||
fmt.Printf(" 结构体方法作为函数值:\n")
|
||
|
||
circle := Circle{Radius: 5}
|
||
areaFunc := circle.Area
|
||
circumferenceFunc := circle.Circumference
|
||
|
||
fmt.Printf(" 圆形: %+v\n", circle)
|
||
fmt.Printf(" 方法值调用 - 面积: %.2f\n", areaFunc())
|
||
fmt.Printf(" 方法值调用 - 周长: %.2f\n", circumferenceFunc())
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateStructEmbedding 演示结构体的嵌入
|
||
func demonstrateStructEmbedding() {
|
||
fmt.Println("4. 结构体的嵌入:")
|
||
|
||
// 具名嵌入
|
||
fmt.Printf(" 具名嵌入:\n")
|
||
|
||
emp := Employee{
|
||
Person: Person{
|
||
Name: "Alice",
|
||
Age: 30,
|
||
Email: "alice@company.com",
|
||
},
|
||
ID: 1001,
|
||
Position: "Manager",
|
||
Salary: 80000,
|
||
}
|
||
|
||
fmt.Printf(" 员工信息: %+v\n", emp)
|
||
fmt.Printf(" 访问嵌入字段: %s, %d\n", emp.Person.Name, emp.Person.Age)
|
||
|
||
// 匿名嵌入
|
||
fmt.Printf(" 匿名嵌入:\n")
|
||
|
||
manager := Manager{
|
||
Person: Person{
|
||
Name: "Bob",
|
||
Age: 35,
|
||
Email: "bob@company.com",
|
||
},
|
||
Department: "Engineering",
|
||
TeamSize: 10,
|
||
}
|
||
|
||
fmt.Printf(" 经理信息: %+v\n", manager)
|
||
|
||
// 直接访问嵌入字段
|
||
fmt.Printf(" 直接访问嵌入字段:\n")
|
||
fmt.Printf(" 姓名: %s\n", manager.Name) // 等同于 manager.Person.Name
|
||
fmt.Printf(" 年龄: %d\n", manager.Age) // 等同于 manager.Person.Age
|
||
fmt.Printf(" 邮箱: %s\n", manager.Email) // 等同于 manager.Person.Email
|
||
|
||
// 调用嵌入类型的方法
|
||
fmt.Printf(" 调用嵌入类型的方法:\n")
|
||
info := manager.GetInfo() // Person 的方法
|
||
fmt.Printf(" GetInfo(): %s\n", info)
|
||
|
||
// 方法重写
|
||
fmt.Printf(" 方法重写:\n")
|
||
|
||
student := Student{
|
||
Person: Person{
|
||
Name: "Charlie",
|
||
Age: 20,
|
||
Email: "charlie@university.edu",
|
||
},
|
||
StudentID: "S12345",
|
||
Major: "Computer Science",
|
||
GPA: 3.8,
|
||
}
|
||
|
||
fmt.Printf(" 学生信息: %+v\n", student)
|
||
|
||
// Student 重写了 GetInfo 方法
|
||
studentInfo := student.GetInfo()
|
||
fmt.Printf(" Student.GetInfo(): %s\n", studentInfo)
|
||
|
||
// 仍然可以访问原始方法
|
||
personInfo := student.Person.GetInfo()
|
||
fmt.Printf(" Person.GetInfo(): %s\n", personInfo)
|
||
|
||
// 多重嵌入
|
||
fmt.Printf(" 多重嵌入:\n")
|
||
|
||
contact := ContactInfo{
|
||
Phone: "123-456-7890",
|
||
Address: "123 Main St",
|
||
}
|
||
|
||
fullEmployee := FullEmployee{
|
||
Person: Person{Name: "David", Age: 28, Email: "david@company.com"},
|
||
Employee: Employee{ID: 1002, Position: "Developer", Salary: 70000},
|
||
ContactInfo: contact,
|
||
}
|
||
|
||
fmt.Printf(" 完整员工信息: %+v\n", fullEmployee)
|
||
fmt.Printf(" 访问各层字段:\n")
|
||
fmt.Printf(" 姓名: %s\n", fullEmployee.Person.Name)
|
||
fmt.Printf(" 职位: %s\n", fullEmployee.Employee.Position)
|
||
fmt.Printf(" 电话: %s\n", fullEmployee.ContactInfo.Phone)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateStructTags 演示结构体的标签
|
||
func demonstrateStructTags() {
|
||
fmt.Println("5. 结构体的标签:")
|
||
|
||
fmt.Printf(" 结构体标签用于元数据,常用于序列化、验证等\n")
|
||
|
||
// 创建带标签的结构体实例
|
||
user := User{
|
||
ID: 1,
|
||
Username: "alice",
|
||
Email: "alice@example.com",
|
||
FullName: "Alice Smith",
|
||
IsActive: true,
|
||
CreatedAt: time.Now(),
|
||
}
|
||
|
||
fmt.Printf(" 用户信息: %+v\n", user)
|
||
|
||
// 使用反射读取标签
|
||
fmt.Printf(" 使用反射读取标签:\n")
|
||
|
||
userType := reflect.TypeOf(user)
|
||
for i := 0; i < userType.NumField(); i++ {
|
||
field := userType.Field(i)
|
||
jsonTag := field.Tag.Get("json")
|
||
dbTag := field.Tag.Get("db")
|
||
validateTag := field.Tag.Get("validate")
|
||
|
||
fmt.Printf(" 字段 %s:\n", field.Name)
|
||
if jsonTag != "" {
|
||
fmt.Printf(" json: %s\n", jsonTag)
|
||
}
|
||
if dbTag != "" {
|
||
fmt.Printf(" db: %s\n", dbTag)
|
||
}
|
||
if validateTag != "" {
|
||
fmt.Printf(" validate: %s\n", validateTag)
|
||
}
|
||
}
|
||
|
||
// 标签的实际应用
|
||
fmt.Printf(" 标签的实际应用:\n")
|
||
fmt.Printf(" - JSON 序列化/反序列化\n")
|
||
fmt.Printf(" - 数据库 ORM 映射\n")
|
||
fmt.Printf(" - 数据验证\n")
|
||
fmt.Printf(" - 配置文件解析\n")
|
||
fmt.Printf(" - API 文档生成\n")
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateAdvancedStructFeatures 演示结构体的高级特性
|
||
func demonstrateAdvancedStructFeatures() {
|
||
fmt.Println("6. 结构体的高级特性:")
|
||
|
||
// 结构体作为映射的值
|
||
fmt.Printf(" 结构体作为映射的值:\n")
|
||
|
||
users := map[string]Person{
|
||
"alice": {Name: "Alice", Age: 25, Email: "alice@example.com"},
|
||
"bob": {Name: "Bob", Age: 30, Email: "bob@example.com"},
|
||
}
|
||
|
||
fmt.Printf(" 用户映射: %+v\n", users)
|
||
|
||
// 结构体切片
|
||
fmt.Printf(" 结构体切片:\n")
|
||
|
||
people := []Person{
|
||
{Name: "Alice", Age: 25, Email: "alice@example.com"},
|
||
{Name: "Bob", Age: 30, Email: "bob@example.com"},
|
||
{Name: "Charlie", Age: 35, Email: "charlie@example.com"},
|
||
}
|
||
|
||
fmt.Printf(" 人员列表:\n")
|
||
for i, person := range people {
|
||
fmt.Printf(" %d: %s (%d岁)\n", i+1, person.Name, person.Age)
|
||
}
|
||
|
||
// 结构体指针切片
|
||
fmt.Printf(" 结构体指针切片:\n")
|
||
|
||
var personPtrs []*Person
|
||
for i := range people {
|
||
personPtrs = append(personPtrs, &people[i])
|
||
}
|
||
|
||
// 修改通过指针
|
||
personPtrs[0].Age = 26
|
||
fmt.Printf(" 修改后的第一个人: %+v\n", people[0])
|
||
|
||
// 空结构体
|
||
fmt.Printf(" 空结构体:\n")
|
||
|
||
type Empty struct{}
|
||
|
||
var empty Empty
|
||
fmt.Printf(" 空结构体大小: %d 字节\n", reflect.TypeOf(empty).Size())
|
||
fmt.Printf(" 空结构体常用于信号传递和集合实现\n")
|
||
|
||
// 使用空结构体实现集合
|
||
set := make(map[string]struct{})
|
||
set["item1"] = struct{}{}
|
||
set["item2"] = struct{}{}
|
||
|
||
fmt.Printf(" 集合: %v\n", getMapKeys(set))
|
||
|
||
// 结构体的内存对齐
|
||
fmt.Printf(" 结构体的内存对齐:\n")
|
||
|
||
type Aligned struct {
|
||
a bool // 1 byte
|
||
b int64 // 8 bytes
|
||
c bool // 1 byte
|
||
}
|
||
|
||
type Optimized struct {
|
||
b int64 // 8 bytes
|
||
a bool // 1 byte
|
||
c bool // 1 byte
|
||
}
|
||
|
||
fmt.Printf(" 未优化结构体大小: %d 字节\n", reflect.TypeOf(Aligned{}).Size())
|
||
fmt.Printf(" 优化后结构体大小: %d 字节\n", reflect.TypeOf(Optimized{}).Size())
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstratePracticalApplications 演示结构体的实际应用
|
||
func demonstratePracticalApplications() {
|
||
fmt.Println("7. 结构体的实际应用:")
|
||
|
||
// 应用1: 配置管理
|
||
fmt.Printf(" 应用1 - 配置管理:\n")
|
||
|
||
config := Config{
|
||
Server: ServerConfig{
|
||
Host: "localhost",
|
||
Port: 8080,
|
||
SSL: false,
|
||
},
|
||
Database: DatabaseConfig{
|
||
Host: "localhost",
|
||
Port: 5432,
|
||
Username: "admin",
|
||
Password: "secret",
|
||
Database: "myapp",
|
||
},
|
||
Cache: CacheConfig{
|
||
Enabled: true,
|
||
TTL: 300,
|
||
MaxSize: 1000,
|
||
},
|
||
}
|
||
|
||
fmt.Printf(" 应用配置: %+v\n", config)
|
||
fmt.Printf(" 服务器地址: %s:%d\n", config.Server.Host, config.Server.Port)
|
||
fmt.Printf(" 数据库连接: %s@%s:%d/%s\n",
|
||
config.Database.Username, config.Database.Host,
|
||
config.Database.Port, config.Database.Database)
|
||
|
||
// 应用2: HTTP 请求/响应
|
||
fmt.Printf(" 应用2 - HTTP 请求/响应:\n")
|
||
|
||
request := HTTPRequest{
|
||
Method: "POST",
|
||
URL: "/api/users",
|
||
Headers: map[string]string{
|
||
"Content-Type": "application/json",
|
||
"Authorization": "Bearer token123",
|
||
},
|
||
Body: `{"name": "Alice", "email": "alice@example.com"}`,
|
||
}
|
||
|
||
response := HTTPResponse{
|
||
StatusCode: 201,
|
||
Headers: map[string]string{
|
||
"Content-Type": "application/json",
|
||
},
|
||
Body: `{"id": 1, "name": "Alice", "email": "alice@example.com"}`,
|
||
}
|
||
|
||
fmt.Printf(" HTTP 请求: %+v\n", request)
|
||
fmt.Printf(" HTTP 响应: %+v\n", response)
|
||
|
||
// 应用3: 数据传输对象 (DTO)
|
||
fmt.Printf(" 应用3 - 数据传输对象:\n")
|
||
|
||
userDTO := UserDTO{
|
||
ID: 1,
|
||
Username: "alice",
|
||
Profile: ProfileDTO{
|
||
FirstName: "Alice",
|
||
LastName: "Smith",
|
||
Bio: "Software Developer",
|
||
},
|
||
Settings: SettingsDTO{
|
||
Theme: "dark",
|
||
Notifications: true,
|
||
Language: "en",
|
||
},
|
||
}
|
||
|
||
fmt.Printf(" 用户 DTO: %+v\n", userDTO)
|
||
|
||
// 应用4: 事件系统
|
||
fmt.Printf(" 应用4 - 事件系统:\n")
|
||
|
||
events := []Event{
|
||
{
|
||
ID: 1,
|
||
Type: "user.created",
|
||
Timestamp: time.Now(),
|
||
Data: map[string]interface{}{
|
||
"user_id": 123,
|
||
"email": "user@example.com",
|
||
},
|
||
},
|
||
{
|
||
ID: 2,
|
||
Type: "order.placed",
|
||
Timestamp: time.Now(),
|
||
Data: map[string]interface{}{
|
||
"order_id": 456,
|
||
"amount": 99.99,
|
||
},
|
||
},
|
||
}
|
||
|
||
fmt.Printf(" 事件列表:\n")
|
||
for _, event := range events {
|
||
fmt.Printf(" 事件 %d: %s (时间: %s)\n",
|
||
event.ID, event.Type, event.Timestamp.Format("15:04:05"))
|
||
fmt.Printf(" 数据: %+v\n", event.Data)
|
||
}
|
||
|
||
// 应用5: 状态机
|
||
fmt.Printf(" 应用5 - 状态机:\n")
|
||
|
||
fsm := StateMachine{
|
||
CurrentState: "idle",
|
||
States: map[string]State{
|
||
"idle": {
|
||
Name: "idle",
|
||
Transitions: map[string]string{
|
||
"start": "running",
|
||
},
|
||
},
|
||
"running": {
|
||
Name: "running",
|
||
Transitions: map[string]string{
|
||
"pause": "paused",
|
||
"stop": "idle",
|
||
},
|
||
},
|
||
"paused": {
|
||
Name: "paused",
|
||
Transitions: map[string]string{
|
||
"resume": "running",
|
||
"stop": "idle",
|
||
},
|
||
},
|
||
},
|
||
}
|
||
|
||
fmt.Printf(" 状态机当前状态: %s\n", fsm.CurrentState)
|
||
|
||
// 状态转换
|
||
if newState, ok := fsm.States[fsm.CurrentState].Transitions["start"]; ok {
|
||
fsm.CurrentState = newState
|
||
fmt.Printf(" 执行 'start' 转换后状态: %s\n", fsm.CurrentState)
|
||
}
|
||
|
||
fmt.Println()
|
||
}// ===
|
||
======= 结构体定义 ==========
|
||
|
||
// 基本结构体
|
||
type Person struct {
|
||
Name string
|
||
Age int
|
||
Email string
|
||
}
|
||
|
||
// Person 的方法
|
||
func (p Person) GetInfo() string {
|
||
return fmt.Sprintf("%s (%d岁) - %s", p.Name, p.Age, p.Email)
|
||
}
|
||
|
||
func (p Person) IsAdult() bool {
|
||
return p.Age >= 18
|
||
}
|
||
|
||
// 地址结构体
|
||
type Address struct {
|
||
Street string
|
||
City string
|
||
Country string
|
||
ZipCode string
|
||
}
|
||
|
||
// 员工结构体(具名嵌入)
|
||
type Employee struct {
|
||
Person Person // 具名嵌入
|
||
ID int
|
||
Position string
|
||
Salary float64
|
||
Address Address
|
||
}
|
||
|
||
// 几何图形结构体
|
||
type Rectangle struct {
|
||
Width float64
|
||
Height float64
|
||
}
|
||
|
||
// Rectangle 的方法
|
||
func (r Rectangle) Area() float64 {
|
||
return r.Width * r.Height
|
||
}
|
||
|
||
func (r Rectangle) Perimeter() float64 {
|
||
return 2 * (r.Width + r.Height)
|
||
}
|
||
|
||
func (r Rectangle) String() string {
|
||
return fmt.Sprintf("Rectangle(%.1f x %.1f)", r.Width, r.Height)
|
||
}
|
||
|
||
// 指针接收者方法
|
||
func (r *Rectangle) Scale(factor float64) {
|
||
r.Width *= factor
|
||
r.Height *= factor
|
||
}
|
||
|
||
// 方法链
|
||
func (r *Rectangle) SetWidth(width float64) *Rectangle {
|
||
r.Width = width
|
||
return r
|
||
}
|
||
|
||
func (r *Rectangle) SetHeight(height float64) *Rectangle {
|
||
r.Height = height
|
||
return r
|
||
}
|
||
|
||
// 圆形结构体
|
||
type Circle struct {
|
||
Radius float64
|
||
}
|
||
|
||
func (c Circle) Area() float64 {
|
||
return 3.14159 * c.Radius * c.Radius
|
||
}
|
||
|
||
func (c Circle) Circumference() float64 {
|
||
return 2 * 3.14159 * c.Radius
|
||
}
|
||
|
||
// 经理结构体(匿名嵌入)
|
||
type Manager struct {
|
||
Person // 匿名嵌入
|
||
Department string
|
||
TeamSize int
|
||
}
|
||
|
||
// 学生结构体(方法重写)
|
||
type Student struct {
|
||
Person
|
||
StudentID string
|
||
Major string
|
||
GPA float64
|
||
}
|
||
|
||
// 重写 Person 的 GetInfo 方法
|
||
func (s Student) GetInfo() string {
|
||
return fmt.Sprintf("学生 %s (%d岁) - %s专业, 学号: %s, GPA: %.1f",
|
||
s.Name, s.Age, s.Major, s.StudentID, s.GPA)
|
||
}
|
||
|
||
// 联系信息结构体
|
||
type ContactInfo struct {
|
||
Phone string
|
||
Address string
|
||
}
|
||
|
||
// 完整员工结构体(多重嵌入)
|
||
type FullEmployee struct {
|
||
Person
|
||
Employee
|
||
ContactInfo
|
||
}
|
||
|
||
// 带标签的结构体
|
||
type User struct {
|
||
ID int `json:"id" db:"id" validate:"required"`
|
||
Username string `json:"username" db:"username" validate:"required,min=3,max=20"`
|
||
Email string `json:"email" db:"email" validate:"required,email"`
|
||
FullName string `json:"full_name" db:"full_name"`
|
||
IsActive bool `json:"is_active" db:"is_active"`
|
||
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||
}
|
||
|
||
// 配置结构体
|
||
type Config struct {
|
||
Server ServerConfig
|
||
Database DatabaseConfig
|
||
Cache CacheConfig
|
||
}
|
||
|
||
type ServerConfig struct {
|
||
Host string
|
||
Port int
|
||
SSL bool
|
||
}
|
||
|
||
type DatabaseConfig struct {
|
||
Host string
|
||
Port int
|
||
Username string
|
||
Password string
|
||
Database string
|
||
}
|
||
|
||
type CacheConfig struct {
|
||
Enabled bool
|
||
TTL int
|
||
MaxSize int
|
||
}
|
||
|
||
// HTTP 请求/响应结构体
|
||
type HTTPRequest struct {
|
||
Method string
|
||
URL string
|
||
Headers map[string]string
|
||
Body string
|
||
}
|
||
|
||
type HTTPResponse struct {
|
||
StatusCode int
|
||
Headers map[string]string
|
||
Body string
|
||
}
|
||
|
||
// 数据传输对象
|
||
type UserDTO struct {
|
||
ID int `json:"id"`
|
||
Username string `json:"username"`
|
||
Profile ProfileDTO `json:"profile"`
|
||
Settings SettingsDTO `json:"settings"`
|
||
}
|
||
|
||
type ProfileDTO struct {
|
||
FirstName string `json:"first_name"`
|
||
LastName string `json:"last_name"`
|
||
Bio string `json:"bio"`
|
||
}
|
||
|
||
type SettingsDTO struct {
|
||
Theme string `json:"theme"`
|
||
Notifications bool `json:"notifications"`
|
||
Language string `json:"language"`
|
||
}
|
||
|
||
// 事件结构体
|
||
type Event struct {
|
||
ID int `json:"id"`
|
||
Type string `json:"type"`
|
||
Timestamp time.Time `json:"timestamp"`
|
||
Data map[string]interface{} `json:"data"`
|
||
}
|
||
|
||
// 状态机结构体
|
||
type StateMachine struct {
|
||
CurrentState string
|
||
States map[string]State
|
||
}
|
||
|
||
type State struct {
|
||
Name string
|
||
Transitions map[string]string
|
||
}
|
||
|
||
// ========== 辅助函数 ==========
|
||
|
||
// 获取映射的键
|
||
func getMapKeys(m map[string]struct{}) []string {
|
||
var keys []string
|
||
for key := range m {
|
||
keys = append(keys, key)
|
||
}
|
||
return keys
|
||
}
|
||
|
||
/*
|
||
运行这个程序:
|
||
go run 04-structs.go
|
||
|
||
学习要点:
|
||
1. 结构体是用户自定义的复合数据类型
|
||
2. 结构体是值类型,赋值和传参会拷贝整个结构体
|
||
3. 结构体可以有方法,支持面向对象编程
|
||
4. 结构体支持嵌入和组合,实现代码复用
|
||
5. 结构体标签用于元数据,常用于序列化和验证
|
||
|
||
结构体的特性:
|
||
1. 类型安全:编译时检查字段类型
|
||
2. 内存效率:字段在内存中连续存储
|
||
3. 可比较性:所有字段可比较时结构体可比较
|
||
4. 零值:所有字段都为零值的结构体
|
||
5. 方法:可以定义方法操作结构体
|
||
|
||
初始化方式:
|
||
1. 零值初始化:var s Struct
|
||
2. 字段名初始化:Struct{Field: value}
|
||
3. 位置初始化:Struct{value1, value2}
|
||
4. 部分初始化:Struct{Field1: value}
|
||
5. 指针初始化:&Struct{} 或 new(Struct)
|
||
|
||
结构体嵌入:
|
||
1. 具名嵌入:显式字段名
|
||
2. 匿名嵌入:直接访问嵌入字段
|
||
3. 方法继承:自动获得嵌入类型的方法
|
||
4. 方法重写:可以重写嵌入类型的方法
|
||
|
||
结构体标签:
|
||
1. 元数据:为字段提供额外信息
|
||
2. 反射访问:通过反射读取标签
|
||
3. 常见用途:JSON、数据库、验证
|
||
4. 格式:`key:"value" key2:"value2"`
|
||
|
||
最佳实践:
|
||
1. 字段名使用驼峰命名
|
||
2. 导出字段首字母大写
|
||
3. 合理组织字段顺序(内存对齐)
|
||
4. 使用指针接收者修改结构体
|
||
5. 适当使用嵌入实现代码复用
|
||
|
||
常见应用场景:
|
||
1. 数据模型和实体
|
||
2. 配置管理
|
||
3. API 请求/响应
|
||
4. 事件和消息
|
||
5. 状态管理
|
||
6. 数据传输对象
|
||
|
||
注意事项:
|
||
1. 结构体是值类型,大结构体传参考虑性能
|
||
2. 嵌入字段的方法可能被重写
|
||
3. 结构体比较要求所有字段可比较
|
||
4. 注意内存对齐对结构体大小的影响
|
||
5. 合理使用标签,避免过度复杂化
|
||
|
||
内存优化:
|
||
1. 字段排序:大字段在前,小字段在后
|
||
2. 使用指针:大结构体考虑使用指针
|
||
3. 空结构体:零内存占用,适合信号传递
|
||
4. 字段对齐:了解内存对齐规则
|
||
*/ |