/* 01-reflection.go - Go 语言反射详解 学习目标: 1. 理解反射的概念和原理 2. 掌握 reflect 包的基本使用 3. 学会反射的类型和值操作 4. 了解反射的应用场景 5. 掌握反射的最佳实践和注意事项 知识点: - 反射的基本概念 - reflect.Type 和 reflect.Value - 类型检查和转换 - 结构体字段和方法的反射 - 反射的性能考虑 - 反射的实际应用 */ package main import ( "fmt" "reflect" "strconv" "strings" "time" ) func main() { fmt.Println("=== Go 语言反射详解 ===\\n") // 演示反射的基本概念 demonstrateReflectionBasics() // 演示类型反射 demonstrateTypeReflection() // 演示值反射 demonstrateValueReflection() // 演示结构体反射 demonstrateStructReflection() // 演示方法反射 demonstrateMethodReflection() // 演示反射的实际应用 demonstratePracticalApplications() // 演示反射的最佳实践 demonstrateBestPractices() } // demonstrateReflectionBasics 演示反射的基本概念 func demonstrateReflectionBasics() { fmt.Println("1. 反射的基本概念:") // 反射的基本概念 fmt.Printf(" 反射的基本概念:\\n") fmt.Printf(" - 反射是程序在运行时检查自身结构的能力\\n") fmt.Printf(" - Go 通过 reflect 包提供反射功能\\n") fmt.Printf(" - 反射基于接口的动态类型信息\\n") fmt.Printf(" - 主要包括类型反射和值反射\\n") fmt.Printf(" - 反射遵循 Go 的类型系统规则\\n") // 反射的核心类型 fmt.Printf(" 反射的核心类型:\\n") fmt.Printf(" - reflect.Type: 表示类型信息\\n") fmt.Printf(" - reflect.Value: 表示值信息\\n") fmt.Printf(" - reflect.Kind: 表示基础类型种类\\n") // 基本反射示例 fmt.Printf(" 基本反射示例:\\n") var x interface{} = 42 // 获取类型信息 t := reflect.TypeOf(x) fmt.Printf(" 类型: %v\\n", t) fmt.Printf(" 类型名称: %s\\n", t.Name()) fmt.Printf(" 类型种类: %v\\n", t.Kind()) // 获取值信息 v := reflect.ValueOf(x) fmt.Printf(" 值: %v\\n", v) fmt.Printf(" 值的类型: %v\\n", v.Type()) fmt.Printf(" 值的种类: %v\\n", v.Kind()) fmt.Printf(" 值的接口: %v\\n", v.Interface()) // 不同类型的反射 fmt.Printf(" 不同类型的反射:\\n") values := []interface{}{ 42, "hello", 3.14, true, []int{1, 2, 3}, map[string]int{"a": 1}, Person{Name: "Alice", Age: 30}, } for i, val := range values { t := reflect.TypeOf(val) v := reflect.ValueOf(val) fmt.Printf(" 值%d: %v (类型: %v, 种类: %v)\\n", i+1, val, t, v.Kind()) } fmt.Println() } // demonstrateTypeReflection 演示类型反射 func demonstrateTypeReflection() { fmt.Println("2. 类型反射:") // 基本类型反射 fmt.Printf(" 基本类型反射:\\n") var i int = 42 var s string = "hello" var f float64 = 3.14 var b bool = true types := []interface{}{i, s, f, b} for _, val := range types { t := reflect.TypeOf(val) fmt.Printf(" %v: 名称=%s, 种类=%v, 大小=%d字节\\n", val, t.Name(), t.Kind(), t.Size()) } // 复合类型反射 fmt.Printf(" 复合类型反射:\\n") // 切片类型 slice := []int{1, 2, 3} sliceType := reflect.TypeOf(slice) fmt.Printf(" 切片类型: %v\\n", sliceType) fmt.Printf(" 元素类型: %v\\n", sliceType.Elem()) fmt.Printf(" 是否为切片: %t\\n", sliceType.Kind() == reflect.Slice) // 映射类型 m := map[string]int{"a": 1, "b": 2} mapType := reflect.TypeOf(m) fmt.Printf(" 映射类型: %v\\n", mapType) fmt.Printf(" 键类型: %v\\n", mapType.Key()) fmt.Printf(" 值类型: %v\\n", mapType.Elem()) // 指针类型 var p *int = &i ptrType := reflect.TypeOf(p) fmt.Printf(" 指针类型: %v\\n", ptrType) fmt.Printf(" 指向类型: %v\\n", ptrType.Elem()) fmt.Printf(" 是否为指针: %t\\n", ptrType.Kind() == reflect.Ptr) // 函数类型 fn := func(int, string) bool { return true } fnType := reflect.TypeOf(fn) fmt.Printf(" 函数类型: %v\\n", fnType) fmt.Printf(" 参数个数: %d\\n", fnType.NumIn()) fmt.Printf(" 返回值个数: %d\\n", fnType.NumOut()) for i := 0; i < fnType.NumIn(); i++ { fmt.Printf(" 参数%d类型: %v\\n", i, fnType.In(i)) } for i := 0; i < fnType.NumOut(); i++ { fmt.Printf(" 返回值%d类型: %v\\n", i, fnType.Out(i)) } // 通道类型 ch := make(chan int) chType := reflect.TypeOf(ch) fmt.Printf(" 通道类型: %v\\n", chType) fmt.Printf(" 通道方向: %v\\n", chType.ChanDir()) fmt.Printf(" 元素类型: %v\\n", chType.Elem()) fmt.Println() } // demonstrateValueReflection 演示值反射 func demonstrateValueReflection() { fmt.Println("3. 值反射:") // 基本值操作 fmt.Printf(" 基本值操作:\\n") var x interface{} = 42 v := reflect.ValueOf(x) fmt.Printf(" 原始值: %v\\n", v.Interface()) fmt.Printf(" 整数值: %d\\n", v.Int()) fmt.Printf(" 是否有效: %t\\n", v.IsValid()) fmt.Printf(" 是否为零值: %t\\n", v.IsZero()) // 值的修改 fmt.Printf(" 值的修改:\\n") var y int = 100 v = reflect.ValueOf(&y) // 需要传递指针才能修改 if v.Kind() == reflect.Ptr && v.Elem().CanSet() { v.Elem().SetInt(200) fmt.Printf(" 修改后的值: %d\\n", y) } // 字符串值操作 var str string = "hello" v = reflect.ValueOf(&str) if v.Kind() == reflect.Ptr && v.Elem().CanSet() { v.Elem().SetString("world") fmt.Printf(" 修改后的字符串: %s\\n", str) } // 切片值操作 fmt.Printf(" 切片值操作:\\n") slice := []int{1, 2, 3} v = reflect.ValueOf(slice) fmt.Printf(" 切片长度: %d\\n", v.Len()) fmt.Printf(" 切片容量: %d\\n", v.Cap()) // 访问切片元素 for i := 0; i < v.Len(); i++ { elem := v.Index(i) fmt.Printf(" 元素[%d]: %v\\n", i, elem.Interface()) } // 映射值操作 fmt.Printf(" 映射值操作:\\n") m := map[string]int{"a": 1, "b": 2, "c": 3} v = reflect.ValueOf(m) fmt.Printf(" 映射长度: %d\\n", v.Len()) // 遍历映射 for _, key := range v.MapKeys() { value := v.MapIndex(key) fmt.Printf(" %v: %v\\n", key.Interface(), value.Interface()) } // 设置映射值 v.SetMapIndex(reflect.ValueOf("d"), reflect.ValueOf(4)) fmt.Printf(" 添加元素后: %v\\n", m) // 创建新值 fmt.Printf(" 创建新值:\\n") // 创建新的整数值 newInt := reflect.New(reflect.TypeOf(0)) newInt.Elem().SetInt(999) fmt.Printf(" 新创建的整数: %v\\n", newInt.Elem().Interface()) // 创建新的切片 sliceType := reflect.SliceOf(reflect.TypeOf(0)) newSlice := reflect.MakeSlice(sliceType, 3, 5) for i := 0; i < newSlice.Len(); i++ { newSlice.Index(i).SetInt(int64(i * 10)) } fmt.Printf(" 新创建的切片: %v\\n", newSlice.Interface()) fmt.Println() } // demonstrateStructReflection 演示结构体反射 func demonstrateStructReflection() { fmt.Println("4. 结构体反射:") // 结构体类型信息 fmt.Printf(" 结构体类型信息:\\n") person := Person{ Name: "Alice", Age: 30, Email: "alice@example.com", } t := reflect.TypeOf(person) v := reflect.ValueOf(person) fmt.Printf(" 结构体名称: %s\\n", t.Name()) fmt.Printf(" 字段数量: %d\\n", t.NumField()) // 遍历结构体字段 fmt.Printf(" 遍历结构体字段:\\n") for i := 0; i < t.NumField(); i++ { field := t.Field(i) value := v.Field(i) fmt.Printf(" 字段%d: %s (类型: %v, 值: %v)\\n", i, field.Name, field.Type, value.Interface()) // 检查字段标签 if tag := field.Tag; tag != "" { fmt.Printf(" 标签: %s\\n", tag) if jsonTag := tag.Get("json"); jsonTag != "" { fmt.Printf(" JSON标签: %s\\n", jsonTag) } } } // 按名称访问字段 fmt.Printf(" 按名称访问字段:\\n") nameField := v.FieldByName("Name") if nameField.IsValid() { fmt.Printf(" Name字段值: %v\\n", nameField.Interface()) } // 修改结构体字段 fmt.Printf(" 修改结构体字段:\\n") // 需要使用指针才能修改 v = reflect.ValueOf(&person) if v.Kind() == reflect.Ptr { v = v.Elem() // 获取指针指向的值 nameField = v.FieldByName("Name") if nameField.CanSet() { nameField.SetString("Bob") fmt.Printf(" 修改后的Name: %s\\n", person.Name) } ageField := v.FieldByName("Age") if ageField.CanSet() { ageField.SetInt(35) fmt.Printf(" 修改后的Age: %d\\n", person.Age) } } // 嵌套结构体 fmt.Printf(" 嵌套结构体:\\n") employee := Employee{ Person: Person{Name: "Charlie", Age: 28}, Title: "Developer", Salary: 80000, } t = reflect.TypeOf(employee) v = reflect.ValueOf(employee) fmt.Printf(" 嵌套结构体字段数: %d\\n", t.NumField()) for i := 0; i < t.NumField(); i++ { field := t.Field(i) value := v.Field(i) fmt.Printf(" 字段%d: %s (类型: %v)\\n", i, field.Name, field.Type) // 如果是嵌套结构体,进一步展开 if field.Type.Kind() == reflect.Struct { fmt.Printf(" 嵌套字段:\\n") nestedValue := value nestedType := field.Type for j := 0; j < nestedType.NumField(); j++ { nestedField := nestedType.Field(j) nestedFieldValue := nestedValue.Field(j) fmt.Printf(" %s: %v\\n", nestedField.Name, nestedFieldValue.Interface()) } } else { fmt.Printf(" 值: %v\\n", value.Interface()) } } fmt.Println() } // demonstrateMethodReflection 演示方法反射 func demonstrateMethodReflection() { fmt.Println("5. 方法反射:") // 方法信息 fmt.Printf(" 方法信息:\\n") person := &Person{Name: "David", Age: 25} t := reflect.TypeOf(person) v := reflect.ValueOf(person) fmt.Printf(" 方法数量: %d\\n", t.NumMethod()) // 遍历方法 for i := 0; i < t.NumMethod(); i++ { method := t.Method(i) fmt.Printf(" 方法%d: %s (类型: %v)\\n", i, method.Name, method.Type) } // 调用方法 fmt.Printf(" 调用方法:\\n") // 按名称获取方法 greetMethod := v.MethodByName("Greet") if greetMethod.IsValid() { // 调用无参数方法 result := greetMethod.Call(nil) if len(result) > 0 { fmt.Printf(" Greet方法返回: %v\\n", result[0].Interface()) } } // 调用带参数的方法 setAgeMethod := v.MethodByName("SetAge") if setAgeMethod.IsValid() { args := []reflect.Value{reflect.ValueOf(30)} setAgeMethod.Call(args) fmt.Printf(" 调用SetAge后,年龄: %d\\n", person.Age) } // 调用带返回值的方法 getInfoMethod := v.MethodByName("GetInfo") if getInfoMethod.IsValid() { result := getInfoMethod.Call(nil) if len(result) > 0 { fmt.Printf(" GetInfo方法返回: %v\\n", result[0].Interface()) } } // 函数值的反射调用 fmt.Printf(" 函数值的反射调用:\\n") fn := func(a, b int) int { return a + b } fnValue := reflect.ValueOf(fn) args := []reflect.Value{ reflect.ValueOf(10), reflect.ValueOf(20), } result := fnValue.Call(args) fmt.Printf(" 函数调用结果: %v\\n", result[0].Interface()) // 方法集的检查 fmt.Printf(" 方法集的检查:\\n") // 检查类型是否实现了某个接口 stringerType := reflect.TypeOf((*fmt.Stringer)(nil)).Elem() personType := reflect.TypeOf(person) fmt.Printf(" Person是否实现Stringer接口: %t\\n", personType.Implements(stringerType)) fmt.Println() } // demonstratePracticalApplications 演示反射的实际应用 func demonstratePracticalApplications() { fmt.Println("6. 反射的实际应用:") // 应用1: JSON 序列化 fmt.Printf(" 应用1 - JSON 序列化:\\n") person := Person{ Name: "Eve", Age: 32, Email: "eve@example.com", } jsonStr := structToJSON(person) fmt.Printf(" JSON序列化结果: %s\\n", jsonStr) // 应用2: 结构体复制 fmt.Printf(" 应用2 - 结构体复制:\\n") original := Person{Name: "Frank", Age: 40} copied := copyStruct(original).(Person) fmt.Printf(" 原始结构体: %+v\\n", original) fmt.Printf(" 复制结构体: %+v\\n", copied) // 应用3: 结构体比较 fmt.Printf(" 应用3 - 结构体比较:\\n") person1 := Person{Name: "Grace", Age: 28} person2 := Person{Name: "Grace", Age: 28} person3 := Person{Name: "Henry", Age: 30} fmt.Printf(" person1 == person2: %t\\n", deepEqual(person1, person2)) fmt.Printf(" person1 == person3: %t\\n", deepEqual(person1, person3)) // 应用4: 配置映射 fmt.Printf(" 应用4 - 配置映射:\\n") config := map[string]interface{}{ "Name": "Iris", "Age": 26, "Email": "iris@example.com", } var configPerson Person mapToStruct(config, &configPerson) fmt.Printf(" 配置映射结果: %+v\\n", configPerson) // 应用5: 验证器 fmt.Printf(" 应用5 - 验证器:\\n") validPerson := Person{Name: "Jack", Age: 25, Email: "jack@example.com"} invalidPerson := Person{Name: "", Age: -5, Email: "invalid"} fmt.Printf(" 有效Person验证: %t\\n", validateStruct(validPerson)) fmt.Printf(" 无效Person验证: %t\\n", validateStruct(invalidPerson)) // 应用6: ORM 映射 fmt.Printf(" 应用6 - ORM 映射:\\n") tableName := getTableName(Person{}) columns := getColumns(Person{}) fmt.Printf(" 表名: %s\\n", tableName) fmt.Printf(" 列名: %v\\n", columns) fmt.Println() } // demonstrateBestPractices 演示反射的最佳实践 func demonstrateBestPractices() { fmt.Println("7. 反射的最佳实践:") // 最佳实践原则 fmt.Printf(" 最佳实践原则:\\n") fmt.Printf(" 1. 谨慎使用反射,优先考虑类型安全的方案\\n") fmt.Printf(" 2. 缓存反射结果以提高性能\\n") fmt.Printf(" 3. 进行充分的错误检查\\n") fmt.Printf(" 4. 避免在热点路径使用反射\\n") fmt.Printf(" 5. 使用接口而不是反射来实现多态\\n") // 性能考虑 fmt.Printf(" 性能考虑:\\n") // 性能测试示例 person := Person{Name: "Test", Age: 30} // 直接访问 vs 反射访问 start := time.Now() for i := 0; i < 100000; i++ { _ = person.Name // 直接访问 } directTime := time.Since(start) start = time.Now() v := reflect.ValueOf(person) nameField := v.FieldByName("Name") for i := 0; i < 100000; i++ { _ = nameField.Interface() // 反射访问 } reflectTime := time.Since(start) fmt.Printf(" 直接访问耗时: %v\\n", directTime) fmt.Printf(" 反射访问耗时: %v\\n", reflectTime) fmt.Printf(" 性能差异: %.2fx\\n", float64(reflectTime)/float64(directTime)) // 错误处理 fmt.Printf(" 错误处理:\\n") // 安全的反射操作 safeReflectOperation := func(obj interface{}, fieldName string) (interface{}, error) { v := reflect.ValueOf(obj) if v.Kind() != reflect.Struct { return nil, fmt.Errorf("对象不是结构体") } field := v.FieldByName(fieldName) if !field.IsValid() { return nil, fmt.Errorf("字段 %s 不存在", fieldName) } return field.Interface(), nil } // 测试安全操作 result, err := safeReflectOperation(person, "Name") if err != nil { fmt.Printf(" 错误: %v\\n", err) } else { fmt.Printf(" 安全获取Name字段: %v\\n", result) } result, err = safeReflectOperation(person, "NonExistent") if err != nil { fmt.Printf(" 预期错误: %v\\n", err) } // 反射的替代方案 fmt.Printf(" 反射的替代方案:\\n") fmt.Printf(" 1. 接口: 使用接口实现多态\\n") fmt.Printf(" 2. 类型断言: 处理已知的有限类型集合\\n") fmt.Printf(" 3. 代码生成: 编译时生成类型安全的代码\\n") fmt.Printf(" 4. 泛型: Go 1.18+ 支持泛型编程\\n") // 何时使用反射 fmt.Printf(" 何时使用反射:\\n") fmt.Printf(" ✓ 序列化/反序列化库\\n") fmt.Printf(" ✓ ORM 框架\\n") fmt.Printf(" ✓ 配置映射\\n") fmt.Printf(" ✓ 测试框架\\n") fmt.Printf(" ✓ 依赖注入容器\\n") fmt.Printf("\\n") fmt.Printf(" ✗ 简单的类型转换\\n") fmt.Printf(" ✗ 已知类型的操作\\n") fmt.Printf(" ✗ 性能敏感的代码\\n") fmt.Printf(" ✗ 可以用接口解决的问题\\n") fmt.Println() } // ========== 类型定义 ========== // Person 人员结构体 type Person struct { Name string `json:"name" db:"name" validate:"required"` Age int `json:"age" db:"age" validate:"min=0,max=150"` Email string `json:"email" db:"email" validate:"email"` } // Greet 问候方法 func (p *Person) Greet() string { return fmt.Sprintf("Hello, I'm %s", p.Name) } // SetAge 设置年龄 func (p *Person) SetAge(age int) { p.Age = age } // GetInfo 获取信息 func (p *Person) GetInfo() string { return fmt.Sprintf("Name: %s, Age: %d, Email: %s", p.Name, p.Age, p.Email) } // String 实现 Stringer 接口 func (p Person) String() string { return fmt.Sprintf("Person{Name: %s, Age: %d}", p.Name, p.Age) } // Employee 员工结构体 type Employee struct { Person Title string `json:"title" db:"title"` Salary float64 `json:"salary" db:"salary"` } // ========== 辅助函数 ========== // structToJSON 将结构体转换为 JSON 字符串 func structToJSON(obj interface{}) string { v := reflect.ValueOf(obj) t := reflect.TypeOf(obj) if v.Kind() != reflect.Struct { return "{}" } var parts []string for i := 0; i < v.NumField(); i++ { field := t.Field(i) value := v.Field(i) // 获取 JSON 标签 jsonTag := field.Tag.Get("json") if jsonTag == "" { jsonTag = strings.ToLower(field.Name) } // 根据类型格式化值 var valueStr string switch value.Kind() { case reflect.String: valueStr = fmt.Sprintf("\\\"%s\\\"", value.String()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: valueStr = fmt.Sprintf("%d", value.Int()) case reflect.Float32, reflect.Float64: valueStr = fmt.Sprintf("%.2f", value.Float()) case reflect.Bool: valueStr = fmt.Sprintf("%t", value.Bool()) default: valueStr = fmt.Sprintf("\\\"%v\\\"", value.Interface()) } parts = append(parts, fmt.Sprintf("\\\"%s\\\": %s", jsonTag, valueStr)) } return "{" + strings.Join(parts, ", ") + "}" } // copyStruct 复制结构体 func copyStruct(src interface{}) interface{} { srcValue := reflect.ValueOf(src) srcType := reflect.TypeOf(src) if srcValue.Kind() != reflect.Struct { return src } // 创建新的结构体实例 newValue := reflect.New(srcType).Elem() // 复制所有字段 for i := 0; i < srcValue.NumField(); i++ { srcField := srcValue.Field(i) newField := newValue.Field(i) if newField.CanSet() { newField.Set(srcField) } } return newValue.Interface() } // deepEqual 深度比较两个值 func deepEqual(a, b interface{}) bool { va := reflect.ValueOf(a) vb := reflect.ValueOf(b) if va.Type() != vb.Type() { return false } switch va.Kind() { case reflect.Struct: for i := 0; i < va.NumField(); i++ { if !deepEqual(va.Field(i).Interface(), vb.Field(i).Interface()) { return false } } return true case reflect.Slice: if va.Len() != vb.Len() { return false } for i := 0; i < va.Len(); i++ { if !deepEqual(va.Index(i).Interface(), vb.Index(i).Interface()) { return false } } return true case reflect.Map: if va.Len() != vb.Len() { return false } for _, key := range va.MapKeys() { aVal := va.MapIndex(key) bVal := vb.MapIndex(key) if !bVal.IsValid() || !deepEqual(aVal.Interface(), bVal.Interface()) { return false } } return true default: return va.Interface() == vb.Interface() } } // mapToStruct 将 map 映射到结构体 func mapToStruct(m map[string]interface{}, dst interface{}) error { dstValue := reflect.ValueOf(dst) if dstValue.Kind() != reflect.Ptr || dstValue.Elem().Kind() != reflect.Struct { return fmt.Errorf("dst 必须是结构体指针") } dstValue = dstValue.Elem() dstType := dstValue.Type() for i := 0; i < dstValue.NumField(); i++ { field := dstType.Field(i) fieldValue := dstValue.Field(i) if !fieldValue.CanSet() { continue } // 从 map 中获取对应的值 if mapValue, ok := m[field.Name]; ok { mapValueReflect := reflect.ValueOf(mapValue) // 类型转换 if mapValueReflect.Type().ConvertibleTo(fieldValue.Type()) { fieldValue.Set(mapValueReflect.Convert(fieldValue.Type())) } } } return nil } // validateStruct 验证结构体 func validateStruct(obj interface{}) bool { v := reflect.ValueOf(obj) t := reflect.TypeOf(obj) if v.Kind() != reflect.Struct { return false } for i := 0; i < v.NumField(); i++ { field := t.Field(i) value := v.Field(i) // 获取验证标签 validateTag := field.Tag.Get("validate") if validateTag == "" { continue } // 解析验证规则 rules := strings.Split(validateTag, ",") for _, rule := range rules { if !validateField(value, strings.TrimSpace(rule)) { return false } } } return true } // validateField 验证单个字段 func validateField(value reflect.Value, rule string) bool { switch rule { case "required": return !value.IsZero() case "email": if value.Kind() == reflect.String { email := value.String() return strings.Contains(email, "@") && strings.Contains(email, ".") } return false default: // 处理 min=0, max=150 等规则 if strings.HasPrefix(rule, "min=") { minStr := strings.TrimPrefix(rule, "min=") if min, err := strconv.Atoi(minStr); err == nil { if value.Kind() == reflect.Int { return value.Int() >= int64(min) } } } if strings.HasPrefix(rule, "max=") { maxStr := strings.TrimPrefix(rule, "max=") if max, err := strconv.Atoi(maxStr); err == nil { if value.Kind() == reflect.Int { return value.Int() <= int64(max) } } } } return true } // getTableName 获取表名 func getTableName(obj interface{}) string { t := reflect.TypeOf(obj) if t.Kind() == reflect.Ptr { t = t.Elem() } // 将结构体名转换为表名(简单的复数形式) name := t.Name() return strings.ToLower(name) + "s" } // getColumns 获取列名 func getColumns(obj interface{}) []string { t := reflect.TypeOf(obj) if t.Kind() == reflect.Ptr { t = t.Elem() } var columns []string for i := 0; i < t.NumField(); i++ { field := t.Field(i) // 获取数据库标签 dbTag := field.Tag.Get("db") if dbTag != "" { columns = append(columns, dbTag) } else { columns = append(columns, strings.ToLower(field.Name)) } } return columns } /* 运行这个程序: go run 01-reflection.go 学习要点: 1. 反射是程序在运行时检查自身结构的能力 2. Go 通过 reflect 包提供反射功能 3. 反射主要包括类型反射和值反射 4. 反射可以用于序列化、ORM、配置映射等场景 5. 反射有性能开销,应该谨慎使用 反射的核心概念: 1. reflect.Type: 表示类型信息 2. reflect.Value: 表示值信息 3. reflect.Kind: 表示基础类型种类 4. 反射遵循 Go 的类型系统规则 5. 反射可以检查和修改值 类型反射: 1. 获取类型信息:reflect.TypeOf() 2. 类型名称和种类:Name(), Kind() 3. 复合类型:Elem(), Key(), In(), Out() 4. 结构体字段:NumField(), Field() 5. 方法信息:NumMethod(), Method() 值反射: 1. 获取值信息:reflect.ValueOf() 2. 值的访问:Interface(), Int(), String() 3. 值的修改:Set(), SetInt(), SetString() 4. 集合操作:Len(), Index(), MapIndex() 5. 创建新值:New(), MakeSlice(), MakeMap() 结构体反射: 1. 字段访问:Field(), FieldByName() 2. 字段信息:Name, Type, Tag 3. 字段修改:CanSet(), Set() 4. 标签解析:Tag.Get() 5. 嵌套结构体处理 方法反射: 1. 方法信息:Method(), MethodByName() 2. 方法调用:Call() 3. 方法类型:Type, NumIn(), NumOut() 4. 接口检查:Implements() 5. 方法集分析 实际应用场景: 1. JSON 序列化/反序列化 2. ORM 数据库映射 3. 配置文件映射 4. 结构体验证 5. 依赖注入 6. 测试框架 7. 代码生成工具 性能考虑: 1. 反射比直接访问慢很多 2. 缓存反射结果可以提高性能 3. 避免在热点路径使用反射 4. 考虑使用接口替代反射 5. 编译时代码生成是更好的选择 最佳实践: 1. 谨慎使用反射,优先考虑类型安全 2. 进行充分的错误检查 3. 缓存反射操作的结果 4. 使用接口实现多态 5. 考虑性能影响 6. 提供清晰的文档说明 注意事项: 1. 反射会破坏类型安全 2. 反射代码难以理解和维护 3. 反射错误只能在运行时发现 4. 反射会影响代码的可读性 5. 反射操作可能导致 panic */