reflect 实践

Written by with ♥ on in Go

这篇文章讲解一些反射的用途,那么反射能做到什么?

获取底层类型

Value 转原始类型

user := v.Interface().(User) // 断言原始类型

遍历结构体字段和方法

for i:=0;i<t.NumField();i++ {
	fmt.Println(t.Field(i).Name)
}

for i:=0;i<t.NumMethod() ;i++  {
	fmt.Println(t.Method(i).Name)
}

修改某个类型的值

Map

var a map[string]int

fmt.Println(reflect.TypeOf(a)) // reflect.Type : map[string]int
fmt.Println(reflect.TypeOf(a).Kind()) // reflect.Kind : map
fmt.Println(reflect.TypeOf(a).Elem()) // reflect.Type : int
fmt.Println(reflect.TypeOf(a).Key())  // reflect.Type : string

// 使用反射初始化 map
reflect.ValueOf(a).Set(reflect.MakeMap(reflect.TypeOf(a))) // error ! ValueOf(a) is not addressable
reflect.ValueOf(&a).Elem().Set(reflect.MakeMap(reflect.TypeOf(a))) // correct

// set key value
reflect.ValueOf(a).SetMapIndex(reflect.ValueOf("abc"), reflect.ValueOf(1))

动态创建值

动态调用函数

type Ref struct {
	key string
	val string
}

func (this *Ref) SayHi(str interface{}) {
	fmt.Println("reflect say:", str)
}

func main() {
	ref := &Ref{key: "hi", val: "girl"}
	iref := reflect.ValueOf(ref)
	fn := iref.MethodByName("SayHi") // 取出函数
	var str = "hello reflect"
	var in []reflect.Value
	in = append(in, reflect.ValueOf(str)) // 拼接参数
	fn.Call(in) // 调用
}

参考资料