Go 语言反射(Reflection)详解

发布时间:2026/5/31 22:39:03

Go 语言反射(Reflection)详解 反射是 Go 语言的高级特性它允许程序在运行时检查变量的类型和值以及动态操作这些变量。反射是 Go 语言中实现通用框架、序列化、依赖注入等功能的基础。一、核心概念Go 的反射主要通过reflect包实现核心类型有reflect.Type描述类型的信息reflect.Value描述值的信息reflect.Kind基本类型分类如struct、int、slice等反射可以做两件事获取类型和值的信息动态修改值前提是值是可设置的settable二、获取类型和值示例packagemainimport(fmtreflect)funcmain(){varxfloat643.14// 获取类型t:reflect.TypeOf(x)fmt.Println(Type:,t)// float64// 获取值v:reflect.ValueOf(x)fmt.Println(Value:,v)// 3.14// 获取 Kindfmt.Println(Kind:,v.Kind())// float64}解释TypeOf返回reflect.Type可以获取类型名、字段等信息ValueOf返回reflect.Value可以获取具体值Kind返回基本分类用于判断类型例如reflect.Struct、reflect.Int等三、反射读取结构体字段反射可以动态读取结构体字段的值和类型typePersonstruct{NamestringAgeint}funcmain(){p:Person{Tom,18}v:reflect.ValueOf(p)t:reflect.TypeOf(p)fori:0;iv.NumField();i{field:v.Field(i)fieldType:t.Field(i)fmt.Printf(Field %s: %v %v\n,fieldType.Name,fieldType.Type,field.Interface())}}输出Field Name: string Tom Field Age: int 18说明NumField()获取字段数量Field(i)获取值t.Field(i)获取类型和字段名Interface()可以将reflect.Value转回普通接口类型四、修改结构体字段必须是指针只有可设置的值才能修改funcmain(){p:Person{Tom,18}v:reflect.ValueOf(p).Elem()// 获取指针指向的值v.FieldByName(Name).SetString(Jerry)v.FieldByName(Age).SetInt(20)fmt.Println(p)// {Jerry 20}}注意ValueOf(p)必须传指针否则修改会失败Elem()获取指针指向的值修改必须使用对应类型的SetXXX方法例如SetString、SetInt五、动态调用方法反射还可以动态调用方法typePersonstruct{Namestring}func(p Person)Greet(msgstring){fmt.Println(p.Name,says:,msg)}funcmain(){p:Person{Tom}v:reflect.ValueOf(p)method:v.MethodByName(Greet)method.Call([]reflect.Value{reflect.ValueOf(Hello)})}输出Tom says: Hello说明MethodByName获取方法Call动态调用需要传[]reflect.Value类型的参数六、总结反射可以在运行时获取变量的类型和值信息reflect.Type获取类型信息reflect.Value获取值修改值必须是可设置的并且通常需要传入指针可以通过反射动态访问字段和调用方法Go 的反射非常强大但滥用会影响性能通常用于框架、序列化、依赖注入等场景七、最佳实践优先使用静态类型操作反射作为最后手段修改结构体字段一定要传指针使用Kind()做类型判断避免 panic反射代码复杂调试时注意Interface()和SetXXX的类型匹配

相关新闻