反射:reflect
遍历结构体的字段,
调用结构体的方法
获取结构体标签的值
package main
import (
"fmt"
"reflect"
)
type Monster struct {
Name string `json:"name"`
Age int `json:"age"`
Score float64 `json:"score"`
Sex string `json:"sex"`
}
func (m Monster) GetSum(n1 int, n2 int) int {
return n1 + n2
}
func (m Monster) Set(name string, age int, score float64, sex string) {
m.Name = name
m.Age = age
m.Score = score
m.Sex = sex
}
func (m Monster) Print() {
fmt.Println("---start---")
fmt.Println(m)
fmt.Println("---end---")
}
//反射
func testStruct(b interface{}) {
rTyp := reflect.TypeOf(b) //main.Monster
rVal := reflect.ValueOf(b) //{tom 20 20 nan}
s := rTyp.Kind() //struct
kd := rVal.Kind() //struct
//如果类别不是一个机构体就退出
if kd != reflect.Struct {
fmt.Println("expect struct")
}
fmt.Println(rTyp)
fmt.Println(rVal)
fmt.Println(s)
fmt.Println(kd)
num := rVal.NumField() //4
fmt.Printf("一个有%v个字段\n", num)
//获取字段的tag和字段的值
for i := 0; i < num; i++ {
fieldName := rTyp.Field(i).Tag.Get("json")
fieldValue := rVal.Field(i)
fmt.Printf("%v=%v\n", fieldName, fieldValue)
}
//操作方法
methodNum := rVal.NumMethod() //小写的方法获取不到
fmt.Printf("strust has %v个方法\n", methodNum)
//方法的索引 是按ASCII码排序
//func (v Value) Call(in []Value) []Value
rVal.Method(1).Call(nil) //调用print方法
//声明这种的切片 []reflect.Value
var params []reflect.Value
params = append(params, reflect.ValueOf(10))
params = append(params, reflect.ValueOf(20))
res := rVal.Method(0).Call(params)
fmt.Printf("res=%v", res[0].Int())
}
func main() {
m := Monster{
Name: "tom",
Age: 10,
Score: 20.0,
Sex: "男",
}
testStruct(m)
}
本作品采用《CC 协议》,转载必须注明作者和本文链接