反射:
在编译时不知道这些变量的具体类型,在运行时检查和更新变量的值、调用变量的方法和变量支持的内在操作。

反射的类型对象(reflect.Type)

使用 reflect.TypeOf() 函数可以获得任意值的类型对象(reflect.Type),程序通过类型对象可以访问任意值的类型信息

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. // 定义一个Enum类型
  7. type Enum int
  8. const (
  9. Zero Enum = 0
  10. )
  11. func main() {
  12. // 声明一个空结构体
  13. type cat struct {
  14. }
  15. // 获取结构体实例的反射类型对象
  16. typeOfCat := reflect.TypeOf(cat{})
  17. // 显示反射类型对象的名称和种类
  18. fmt.Println(typeOfCat.Name(), typeOfCat.Kind())
  19. // 获取Zero常量的反射类型对象
  20. typeOfA := reflect.TypeOf(Zero)
  21. // 显示反射类型对象的名称和种类
  22. fmt.Println(typeOfA.Name(), typeOfA.Kind())
  23. }
  24. 输出
  25. cat struct
  26. Enum int

反射种类(Kind)

种类(Kind)指的是对象归属的品种, Kind 方法不会像 Type 方法一样区分 自定义的MyInt 和 int。

  1. type Kind uint
  2. const (
  3. Invalid Kind = iota // 非法类型
  4. Bool // 布尔型
  5. Int // 有符号整型
  6. Int8 // 有符号8位整型
  7. Int16 // 有符号16位整型
  8. Int32 // 有符号32位整型
  9. Int64 // 有符号64位整型
  10. Uint // 无符号整型
  11. Uint8 // 无符号8位整型
  12. Uint16 // 无符号16位整型
  13. Uint32 // 无符号32位整型
  14. Uint64 // 无符号64位整型
  15. Uintptr // 指针
  16. Float32 // 单精度浮点数
  17. Float64 // 双精度浮点数
  18. Complex64 // 64位复数类型
  19. Complex128 // 128位复数类型
  20. Array // 数组
  21. Chan // 通道
  22. Func // 函数
  23. Interface // 接口
  24. Map // 映射
  25. Ptr // 指针
  26. Slice // 切片
  27. String // 字符串
  28. Struct // 结构体
  29. UnsafePointer // 底层指针
  30. )

指针

reflect.Elem() 方法获取这个指针指向的元素类型

结构体

通过反射值对象 reflect.Type 的 NumField() 和 Field() 方法获得结构体成员的详细信息。

方法 说明
Field(i int) StructField 根据索引返回索引对应的结构体字段的信息,当值不是结构体或索引超界时发生宕机
NumField() int 返回结构体成员字段数量,当类型不是结构体或索引超界时发生宕机
FieldByName(name string) (StructField, bool) 根据给定字符串返回字符串对应的结构体字段的信息,没有找到时 bool 返回 false,当类型不是结构体或索引超界时发生宕机
FieldByIndex(index []int) StructField 多层成员访问时,根据 []int 提供的每个结构体的字段索引,返回字段的信息,没有找到时返回零值。当类型不是结构体或索引超界时发生宕机
FieldByNameFunc(match func(string) bool) (StructField,bool) 根据匹配函数匹配需要的字段,当值不是结构体或索引超界时发生宕机

结构体标签

  • func (tag StructTag) Get(key string) string:根据 Tag 中的键获取对应的值,例如key1:"value1" key2:"value2"的 Tag 中,可以传入“key1”获得“value1”。
  • func (tag StructTag) Lookup(key string) (value string, ok bool):根据 Tag 中的键,查询值是否存在。

注意:在 json: 和 “type” 之间增加了一个空格,这种写法没有遵守结构体标签的规则,因此无法通过 Tag.Get 获取到正确的 json 对应的值。这个错误在开发中非常容易被疏忽,造成难以察觉的错误。所以将第 12 行代码修改为下面的样子,则可以正常打印。