Go Reflect 提高反射
反射:在程序编译期将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期获取类型的反射信息,并且有能力修改它们。
反射会拖慢运行速度,非必要不使用。
Go语言反射(reflection)简述:reflect.ValueOf(a)
:返回a的值,typeOfA := reflect.TypeOf(a)
:获取a的反射信息,typeOfA中装的就是反射信息。
- 类型:
typeOfA.Name()
:返回类型名,如type A struct{}
中的A、type Enum int
中的EnumtypeOfA.Kind()
:比typeOfA.Name()
返回更抽象的类,如type A struct{}
中的struct、ptr(指针)、type Enum int
中的int- int、string、bool的类型,
typeOfA.Name()
和typeOfA.Kind()
返回的是一样的。
- 指针:若a为指针,可以通过
typeOfA.Elem()
获取对象反射信息。 - 获取结构体的成员类型:
Field(i int) StructField
获取指定索引的类型信息
NumField() int
获取结构体字段数量;
FieldByName(name string) (StructField, bool)
获取指定字段名的类型信息
package main
import (
"fmt"
"reflect"
)
func main() {
// 声明一个空结构体
type cat struct {
Name string
// 带有结构体tag的字段
Type int `json:"type" id:"100"`
}
// 创建cat的实例
ins := cat{Name: "mimi", Type: 1}
// 获取结构体实例的反射类型对象
typeOfCat := reflect.TypeOf(ins)
// 遍历结构体所有成员
for i := 0; i < typeOfCat.NumField(); i++ {
// 获取每个成员的结构体字段类型
fieldType := typeOfCat.Field(i)
// 输出成员名和tag
fmt.Printf("name: %v tag: '%v'\n", fieldType.Name, fieldType.Tag)
}
// 通过字段名, 找到字段类型信息
if catType, ok := typeOfCat.FieldByName("Type"); ok {
// 从tag中取出需要的tag
fmt.Println(catType.Tag.Get("json"), catType.Tag.Get("id"))
}
}