反射
package main
import (
"fmt"
"reflect"
)
type MyMysql struct {
Host string `ini:"host"`
Port int `ini:"port"`
}
type MyRedis struct {
Host string `ini:"host"`
Port int `ini:"port"`
}
type conf struct {
MyMysql `ini:"mmm"`
MyRedis `ini:"rrr"`
}
func main() {
var v conf
//获取结构体的值信息
v1 := reflect.ValueOf(&v)
//获取结构体的类型信息
t1 := reflect.TypeOf(&v)
fmt.Println("1", v1, t1) //&{{ 0} { 0}} *main.conf
//因为是指针,所以需要Elem指向地址后才能获取结构体字段信息
field1 := t1.Elem().Field(1)
fmt.Println("2", field1, field1.Name, field1.Type) //2 {MyRedis main.MyRedis ini:"rrr" 24 [1] true} MyRedis main.MyRedis
//这样就可以拿到结构体中的字段信息
field2 := v1.Elem().Field(1)
fmt.Println("3", field2, field2.Kind(), field2.Type()) //3 { 0} struct main.MyRedis 通过比较可以看到为什么要用Type
//就可以通过后面的rrr或者mmm判断是否正确拿到结构中的字段
fmt.Println(field1.Tag.Get("ini"), field1.Name, field1.Index, field1.Type)
fmt.Println("---------------------------------------------------")
//通过指定的name(MyRedis)获取到对应的结构体字段
obj := v1.Elem().FieldByName(field1.Name)
fmt.Println("obj", obj, obj.Kind(), obj.Type()) //{ 0} main.MyRedis struct
//获取Type,通过可以它获得当前对应的结构体的信息
objType := obj.Type()
fmt.Println(objType, objType.Kind(), objType.Name()) //main.MyRedis struct MyRedis
//获取当前结构体中有几个成员字段数量
num := objType.NumField()
fmt.Println(num) //2
//根据索引,返回索引对应的结构体字段的信息。 通过Type才能获取信息
field := objType.Field(1)
fmt.Println(field) //{Port int ini:"port" 16 [1] false}
//可以通过比较port判断field.Name是否一致
fmt.Println(field.Tag.Get("ini"), field.Name, field.Index, field.Type) //port Port [1] int
fmt.Println(field.Type.Kind(), field.Type) //int 通过最后的类型进行判断
fileOjb := obj.FieldByName(field.Name) //需要从{ 0} 取出
fmt.Println("fileOjb:", fileOjb)//fileOjb: 0
switch field.Type.Kind() {
case reflect.String:
case reflect.Int:
fileOjb.SetInt(int64(1000))
}
fmt.Println(v.MyRedis.Port)//{{ 0} { 1000}}
}
不难就是方法太多了,都是一步一步打印出来的,纯属苦力活,
取类型:
类型中存放着结构体的信息,因为需要判断
等会写 要上大号
浙公网安备 33010602011771号