一、使用反射遍历结构体字段并调用方法
package main
import (
"fmt"
"reflect"
)
//定义一个结构体
type Monster struct {
Name string `json:"name"`
Age int `json:"monster_age"`
Score float64
Sex string
}
//定义一个方法
func (s Monster) Print() {
fmt.Println("start")
fmt.Println(s)
fmt.Println("end")
}
//定义一个方法计算一个数
func (s Monster) GetSum(n1,n2 int) int {
return n1 + n2
}
//定义一个set方法赋值
func (s Monster) Set(name string, age int, score float64,sex string) {
s.Name = name
s.Age = age
s.Score = score
s.Sex = sex
}
//定义一个函数
func TestStruct(a interface{}) {
//获取结构的类型
typ := reflect.TypeOf(a)
//获取结构体的值
val := reflect.ValueOf(a)
//获取结构体的类别
kind := val.Kind()
//判断类别
if kind != reflect.Struct{
fmt.Println("expect struct")
return
}
//获取到结构体有几个字段
num := val.NumField()
fmt.Println("num=",num)
//遍历结构字段
for i :=0;i <num ;i++ {
fmt.Printf("Field %d: 值为=%v\n",i,val.Field(i))
getVal := typ.Field(i).Tag.Get("json")
//如果该字段有Tag就显示
if getVal != ""{
fmt.Printf("Field %d: tag为=%v\n",i,getVal)
}
}
//获取到该结构体绑定的方法个数,方法名要大写才行
method := val.NumMethod()
fmt.Println("method=",method)
//调用结构体的方法
val.Method(1).Call(nil)
//声明一个reflect.Value类型切片
var params []reflect.Value
params = append(params,reflect.ValueOf(10))
params = append(params,reflect.ValueOf(40))
//传入的参数
res := val.Method(0).Call(params)
fmt.Println("res=",res[0].Int())
}
func main() {
monster := Monster{Name:"老黄",Age:55,Score:56.1}
//monster.Set("老黄",40,30.4,"jjj")
TestStruct(monster)
}
![](https://img-blog.csdnimg.cn/3a9dfd948916423cabb004c6d34a454f.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6bit6bit6ICB5p2_,size_14,color_FFFFFF,t_70,g_se,x_16)
二、使用反射改变结构体的值
package main
import (
"fmt"
"reflect"
)
//定义一个结构体
type Monster struct {
Name string `json:"name"`
Age int `json:"monster_age"`
Score float64
Sex string
}
//定义一个方法
func (s Monster) Print() {
fmt.Println("start")
fmt.Println(s)
fmt.Println("end")
}
//定义一个方法计算一个数
func (s Monster) GetSum(n1,n2 int) int {
return n1 + n2
}
//定义一个set方法赋值
func (s Monster) Set(name string, age int, score float64,sex string) {
s.Name = name
s.Age = age
s.Score = score
s.Sex = sex
}
//定义一个函数
func TestStruct(a interface{}) {
//获取结构的类型
typ := reflect.TypeOf(a)
//获取结构体的值
val := reflect.ValueOf(a)
//获取结构体的类别
kind := val.Elem().Kind()
//判断类别
if kind != reflect.Struct{
fmt.Println("expect struct")
return
}
//获取到结构体有几个字段
num := val.Elem().NumField()
//使用反射改变结构体的值
val.Elem().Field(0).SetString("老王")
fmt.Println("num=",num)
//遍历结构字段
for i :=0;i <num ;i++ {
fmt.Printf("Field %d: 值为=%v\n",i,val.Elem().Field(i))
getVal := typ.Elem().Field(i).Tag.Get("json")
//如果该字段有Tag就显示
if getVal != ""{
fmt.Printf("Field %d: tag为=%v\n",i,getVal)
}
}
//获取到该结构体绑定的方法个数,方法名要大写才行
method := val.NumMethod()
fmt.Println("method=",method)
//调用结构体的方法
val.Method(1).Call(nil)
//声明一个reflect.Value类型切片
var params []reflect.Value
params = append(params,reflect.ValueOf(10))
params = append(params,reflect.ValueOf(40))
//传入的参数
res := val.Method(0).Call(params)
fmt.Println("res=",res[0].Int())
}
func main() {
monster := Monster{Name:"老黄",Age:55,Score:56.1}
//monster.Set("老黄",40,30.4,"jjj")
TestStruct(&monster)
}
![](https://img-blog.csdnimg.cn/2fd505dca2ec400b944baab670682b91.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6bit6bit6ICB5p2_,size_12,color_FFFFFF,t_70,g_se,x_16)
三、使用反射操作适配器
package demo21
import (
"reflect"
"testing"
)
func TestReflectFunc(t *testing.T) {
call1 := func(v1 int, v2 int){
t.Log(v1,v2)
}
call2 := func(v1 int, v2 int,s string){
t.Log(v1,v2,s)
}
var (
function reflect.Value
inValue []reflect.Value
n int
)
bridge := func(call interface{},args ...interface{}) {
n = len(args)
inValue = make([]reflect.Value,n)
for i:=0;i<n ;i++ {
inValue[i] = reflect.ValueOf(args[i])
}
function = reflect.ValueOf(call)
function.Call(inValue)
}
bridge(call1,1,2)
bridge(call2,1,2,"hell")
}
![](https://img-blog.csdnimg.cn/05cffef88bde45458d990972903affde.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6bit6bit6ICB5p2_,size_13,color_FFFFFF,t_70,g_se,x_16)
四、使用反射操作任意结构体
package main
import (
"fmt"
"reflect"
)
type User struct {
UserId string
Name string
}
func main() {
var (
model *User
sv reflect.Value
)
model = &User{}
sv = reflect.ValueOf(model)
fmt.Println("reflect.ValueOf=",sv.Kind().String())
sv = sv.Elem()
fmt.Println("reflect.ValueOf.Elem=",sv.Kind().String())
sv.FieldByName("UserId").SetString("123456")
sv.FieldByName("Name").SetString("tom")
fmt.Println(*model)
}
![](https://img-blog.csdnimg.cn/b9704e15976e439889c381b5a3734308.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6bit6bit6ICB5p2_,size_14,color_FFFFFF,t_70,g_se,x_16)
五、使用反射创建结构体并使用
package main
import (
"fmt"
"reflect"
)
type User struct {
UserId string
Name string
}
func main() {
var (
model *User
sv reflect.Type
elem reflect.Value
)
sv = reflect.TypeOf(model)
fmt.Println("reflect.TypeOf=",sv.Kind().String())
sv = sv.Elem()
fmt.Println("reflect.ValueOf.Elem=",sv.Kind().String())
//New返回一个value类型值,该值持有一个指向类型为typ的新申请的零值的指针
elem = reflect.New(sv)
//model创建的user结构体变量
model = elem.Interface().(*User)
elem = elem.Elem()
elem.FieldByName("UserId").SetString("12345")
elem.FieldByName("Name").SetString("jack")
fmt.Println(*model)
}
![](https://img-blog.csdnimg.cn/c2b794ee468f4515a39e8b1c5e808e75.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6bit6bit6ICB5p2_,size_14,color_FFFFFF,t_70,g_se,x_16)
六、练习
![](https://img-blog.csdnimg.cn/cdfb40e17c074ca59610175fec7dc4ba.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6bit6bit6ICB5p2_,size_18,color_FFFFFF,t_70,g_se,x_16)
package main
import (
"fmt"
"reflect"
)
type Cal struct {
Num1 int
Num2 int
}
//定义一个方法
func (this Cal) GetSub(name string) {
fmt.Println(name,"完成了",this.Num1,"-",this.Num2, "=",this.Num1 - this.Num2)
}
//定义一个函数
func test05(re interface{}) {
elem := reflect.ValueOf(re).Elem()
//给结构体字段赋值
elem.Field(0).SetInt(8)
elem.Field(1).SetInt(3)
//遍历所有字段信息
for i := 0;i<elem.NumField() ;i++ {
fmt.Println("结构体字段值为",elem.Field(i))
}
//调用结构体方法
var par []reflect.Value
par = append(par,reflect.ValueOf("tom"))
elem.Method(0).Call(par)
}
func main() {
cal := Cal{}
test05(&cal)
}
![](https://img-blog.csdnimg.cn/73028d156e9f4dbe873eceb58abf686f.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6bit6bit6ICB5p2_,size_13,color_FFFFFF,t_70,g_se,x_16)