Go语言的反射(reflection)是一种强大的机制,它允许程序在运行时检查、修改变量的类型和值。反射主要使用reflect
包来实现。以下是一些常见的反射应用场景和示例:
- 类型检查:使用
reflect.TypeOf()
函数获取变量的类型信息。
package main import ( "fmt" "reflect" ) func main() { var num int = 42 var str string = "hello" fmt.Println("Type of num:", reflect.TypeOf(num)) // 输出: Type of num: int fmt.Println("Type of str:", reflect.TypeOf(str)) // 输出: Type of str: string }
- 获取变量值:使用
reflect.ValueOf()
函数获取变量的值。
package main import ( "fmt" "reflect" ) func main() { var num int = 42 var str string = "hello" fmt.Println("Value of num:", reflect.ValueOf(num)) // 输出: Value of num: 42 fmt.Println("Value of str:", reflect.ValueOf(str)) // 输出: Value of str: hello }
- 修改变量值:使用
reflect.Value
类型的SetInt()
、SetString()
等方法修改变量的值。
package main import ( "fmt" "reflect" ) func main() { var num int = 42 var str string = "hello" fmt.Println("Original value of num:", num) // 输出: Original value of num: 42 fmt.Println("Original value of str:", str) // 输出: Original value of str: hello valNum := reflect.ValueOf(&num).Elem() valStr := reflect.ValueOf(&str).Elem() valNum.SetInt(100) valStr.SetString("world") fmt.Println("Modified value of num:", num) // 输出: Modified value of num: 100 fmt.Println("Modified value of str:", str) // 输出: Modified value of str: world }
- 遍历结构体字段:使用
reflect.Type
类型的Name()
和PkgPath()
方法获取字段信息,使用reflect.Value
类型的FieldByName()
方法获取字段值。
package main import ( "fmt" "reflect" ) type Person struct { Name string Age int } func main() { p := Person{Name: "Alice", Age: 30} t := reflect.TypeOf(p) for i := 0; i < t.NumField(); i++ { field := t.Field(i) value := reflect.ValueOf(p).Field(i) fmt.Printf("Field Name: %s, Field Value: %v\n", field.Name, value.Interface()) } }
- 调用方法:使用
reflect.Type
类型的Name()
方法获取方法信息,使用reflect.Value
类型的MethodByName()
方法获取方法值,然后使用Call()
方法调用方法。
package main import ( "fmt" "reflect" ) type Calculator struct{} func (c Calculator) Add(a, b int) int { return a + b } func main() { calc := Calculator{} method := reflect.ValueOf(calc).MethodByName("Add") result := method.Call([]reflect.Value{reflect.ValueOf(10), reflect.ValueOf(20)}) fmt.Println("Add result:", result[0].Int()) // 输出: Add result: 30 }
这些示例展示了Go语言反射的基本用法。需要注意的是,反射通常会降低程序的性能,因此在性能敏感的场景中要谨慎使用。