继续
This commit is contained in:
892
golang-learning/04-data-structures/04-structs.go
Normal file
892
golang-learning/04-data-structures/04-structs.go
Normal file
@@ -0,0 +1,892 @@
|
||||
/*
|
||||
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. 字段对齐:了解内存对齐规则
|
||||
*/
|
Reference in New Issue
Block a user