// 反射字段操作 u := User{"tom", 27, "beijing"} // elem := reflect.Indirect(reflect.ValueOf(&u)) // 等效于下方 elem := reflect.ValueOf(&u).Elem() t := elem.Type()
fmt.Println("before user:", u) for i := 0; i < t.NumField(); i++ { // 反射获取字段的元信息,例如:名称、Tag 等 ft := t.Field(i) fmt.Printf("field name:%s\t", ft.Name) fmt.Printf("Tags:%s\t", ft.Tag) // 获取所有tag fmt.Printf("Tag json:%s\n", ft.Tag.Get("json")) // 根据tag名字获取
// 反射修改字段的值() fv := elem.Field(i) if fv.CanSet() { if fv.Kind() == reflect.Int { fmt.Println("change age to 30") fv.SetInt(30) } } } fmt.Println("after user:", u)
/* before user: {tom 27 beijing} field name:Name Tags:json:"name",yaml:"Name" Tag json:name field name:Age Tags:json:"age,omitempty" Tag json:age,omitempty change age to 30 field name:From Tags:json:"from" Tag json:from after user: {tom 30 beijing} */
可以看到 age字段被修改了
四、反射对象的方法
可以通过 Value 的 Method() 方法或 Type 的 Method() 方法,两种形式获取对象方法信息进行反射调用,略有不同,示例如下:
if mv.IsValid() { if v := mv.Call(nil); len(v) > 0 { if err, ok := v[0].Interface().(error); ok { log.Fatal(err) } } } }
//通过函数名字调用 fm := rv.MethodByName("Hi") if fm.IsValid() { if v := fm.Call(nil); len(v) > 0 { if err, ok := v[0].Interface().(error); ok { log.Fatal(err) } } } /* 1 {Hi func(m_reflect.User) <func(m_reflect.User) Value> 0} hi hi hi */
t := reflect.PtrTo(rt) for i := 0; i < t.NumMethod(); i++ { mt := t.Method(i) // 通过value
fmt.Println(mt)
param := []reflect.Value{reflect.ValueOf(&u)} if mt.Func.IsValid() { if v := mt.Func.Call(param); len(v) > 0 { if err, ok := v[0].Interface().(error); ok { log.Fatal(err) } } }
// 通过接口来获取任意参数,然后一一揭晓 funcDoFiledAndMethod(input interface{}) { getType := reflect.TypeOf(input) fmt.Println("get Type is :", getType.Name())
getValue := reflect.ValueOf(input) fmt.Println("get all Fields is:", getValue)
// 获取字段 // 1. 先获取interface的reflect.Type,然后通过NumField进行遍历 // 2. 再通过reflect.Type的Field获取其Field // 3. 最后通过reflect.Value获取Field的Interface()得到对应的value for i := 0; i < getType.NumField(); i++ { field := getType.Field(i) value := getValue.Field(i).Interface() fmt.Printf("%s: %v = %v\n", field.Name, field.Type, value) }
// 获取方法 // 1. 先获取interface的reflect.Type,然后通过.NumMethod进行遍历 for i := 0; i < getType.NumMethod(); i++ { m := getType.Method(i) fmt.Printf("%s: %v\n", m.Name, m.Type) } } /* get Type is : User get all Fields is: {1 0 2} Name: string = 1 Age: int = 0 From: string = 2 Hi: func(m_reflect.User) */