Go Reflect 提高反射

反射:在程序编译期将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期获取类型的反射信息,并且有能力修改它们。

反射会拖慢运行速度,非必要不使用。

Go语言反射(reflection)简述reflect.ValueOf(a):返回a的值,typeOfA := reflect.TypeOf(a):获取a的反射信息,typeOfA中装的就是反射信息。

  • 类型:
    • typeOfA.Name():返回类型名,如type A struct{}中的A、type Enum int中的Enum
    • typeOfA.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"))
    }
}
posted @ 2022-12-04 18:46  好人~  阅读(14)  评论(0编辑  收藏  举报