1. 概述

golang提供一种机制在运行时更新和检查变量的值,调用变量的方法和变量支持的操作。但是在编译时候不知道这些变量的具体类型, 这种机制成为反射。

1.1. reflect 包

Go语言中的反射是由 reflect 包提供支持的,它定义了两个重要的类型 Type 和 Value 任意接口值在反射中都可以理解为由 reflect.Type 和 reflect.Value 两部分组成, 并且 reflect 包提供了 reflect.TypeOf 和 reflect.ValueOf 两个函数来获取任意对象的 Value 和 Type。

1.2. 指针和指针指向的元素

package main

import (
	"fmt"
	"reflect"
)

func main100() {
	// 声明一个空结构体
	type cat struct {
	}
	// 创建cat的实例
	ins := &cat{}
	// 获取结构体实例的反射类型对象
	typeOfCat := reflect.TypeOf(ins)
	// 显示反射类型对象的名称和种类
	fmt.Printf("name:'%v' kind:'%v'\n", typeOfCat.Name(), typeOfCat.Kind())
	// 取类型的元素
	typeOfCat = typeOfCat.Elem()
	// 显示反射类型对象的名称和种类
	fmt.Printf("element name: '%v', element kind: '%v'\n", typeOfCat.Name(), typeOfCat.Kind())
}

测试结果如下

name:'' kind:'ptr'
element name: 'cat', element kind: 'struct'

指针类型的typename都是空的, typekind是ptr的,指针类型item是具体元素类型。

1.3. 使用反射获取结构体的成员类型

  • field: 根据索引获取到具体结构体字段信息。
  • NumFiedLd: 获取字段个数。
  • FieldByName: 跟进名字获取对应结构体字段信息。
  • FieldByIndex: 根据索引获取对应结构体的字段信息。
  • FieldByNameFunc: 根据匹配函数返回对应的字段。