golang反射常见用法
Posted luobote11
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang反射常见用法相关的知识,希望对你有一定的参考价值。
一直都知道golang的反射语法,但是对于什么场景下使用reflect反射没有概念,肝了两个晚上,整理了下用到过的场景:
1、框架接口的入参。
2、基类寻找子类的类型,并调用其变量、方法。
下面代码,包含了常见reflect的使用场景:
1 package reflect 2 3 import ( 4 "errors" 5 "fmt" 6 "reflect" 7 "testing" 8 "time" 9 ) 10 11 type callback func() 12 13 type User struct { 14 Name string 15 Age int 16 } 17 18 func (i *User) MyMethod(cb interface{}) error { 19 fmt.Println("MyMethod is me.") 20 f := cb.(interface{}).(func()) //确定类型直接转换 21 f() 22 return errors.New("MyMethod return no error!") 23 } 24 25 func TestReflect(t *testing.T) { 26 u := User{ 27 Name: "myName", 28 Age: 23, 29 } 30 getType := reflect.TypeOf(u) //获取类型 31 fmt.Println(getType) 32 getPointType := reflect.TypeOf(&u) //获取指针类型 33 fmt.Println(getPointType) 34 getValue := reflect.ValueOf(u) //获取值 35 fmt.Println(getValue) 36 getPointValue := reflect.ValueOf(&u) //获取值指针 37 fmt.Println(getPointValue) 38 for i := 0; i < getType.NumField(); i++ { //取各成员变量 39 field := getType.Field(i) 40 value := getValue.Field(i).Interface() 41 fmt.Printf("%s: %v = %v ", field.Name, field.Type, value) 42 } 43 for i := 0; i < getPointType.NumMethod(); i++ { //获取方法 44 m := getPointType.Method(i) 45 fmt.Printf("%s: %v ", m.Name, m.Type) 46 } 47 f := func() { 48 fmt.Println("Func is me.") 49 } 50 go func() { //取method运行 51 fun := getPointValue.MethodByName("MyMethod") 52 input := []reflect.Value{reflect.ValueOf(f)} 53 values := fun.Call(input) 54 err := values[0].Interface().(error) 55 fmt.Println(err) 56 //上述一行写法 57 //fmt.Println(reflect.ValueOf(&u).MethodByName("MyMethod").Call([]reflect.Value{ 58 // reflect.ValueOf(f)})[0].Interface().(error)) 59 }() 60 go func() { //不用指针reflect,调用method、修改成员变量,均需要使用指针类型。 61 defer func() { 62 fmt.Println(recover()) //panic: reflect: call of reflect.Value.Call on zero Value 63 }() 64 values := getValue.MethodByName("MyMethod").Call([]reflect.Value{ 65 reflect.ValueOf(f)}) 66 err := values[0].Interface().(error) 67 fmt.Println(err) 68 }() 69 time.Sleep(time.Second) 70 }
基本概念参考:
以上是关于golang反射常见用法的主要内容,如果未能解决你的问题,请参考以下文章
Golang实践录:利用反射reflect构建通用打印结构体接口