反射

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}}
}

  不难就是方法太多了,都是一步一步打印出来的,纯属苦力活,

取类型:

   类型中存放着结构体的信息,因为需要判断

  等会写 要上大号

 

posted @ 2022-03-08 05:53  咖喱给给啊  阅读(26)  评论(0)    收藏  举报