golang的断言与反射笔记

78 阅读2分钟

import (
	"fmt"
	"reflect"
)

type User struct {
	Name string
	age  int
}

type Student struct {
	Name string `json:"Name" feifei:"Name_xxx"`
	age  StudentAge
}

type StudentAge struct {
	Name string
	age  int
}

func main() {
	user := User{
		Name: "我是User",
		age:  4,
	}
	studentage := StudentAge{
		Name: "我是StudentAge",
		age:  5,
	}
	student := Student{
		Name: "我是Student",
		age:  studentage,
	}
	DuanYan(student, user)
	FanShe(&student, user)
	fmt.Println(student)
}

// 断言是什么,断言是声明这个变量他是什么,有时候系统不知道变量是什么,就需要你断言
// 将数据放入interface{}后需要断言才能使用,不然系统不知道他是什么,可以配合用v.(type)知道v的类型,也可以用v.(结构体)直接断言
// 如果断言失败则会返回错误信息errs,ok := err.(validator.ValidationErrors),ok就是错误信息
func DuanYan(v interface{}, o any) {
	//判断结构体的类型
	switch v.(type) {
	case User:
		fmt.Println(v.(User).Name)
	case Student:
		fmt.Println(v.(Student).Name)
	}

	//反射是什么,断言的变量修改起来会很麻烦。反射可以知道进来的数据他的原始数据类型并可以进行操作
	//反射的优点是可以动态修改数据值
	//缺点是性能不好,可读性不好
	//TypeOf可以直接知道他是什么类型 结果为 main.User
	t := reflect.TypeOf(v)
	fmt.Println("我的类型是:", t)
	//TypeOf可以直接得到他结构体里的值 结果为 {我是User 4}
	y := reflect.ValueOf(v)
	fmt.Println("我的所有的值是:", y)
	//t.NumField()结构体的总数量,y.Field(i)结构体对应的索引
	for i := 0; i < t.NumField(); i++ {
		fmt.Println(
			"获取字段名:", t.Field(i).Name,
			"\r\n获取json内容:", t.Field(i).Tag.Get("feifei"),
			"\r\n获取字段对应内容:", y.Field(i),
			"\r\n获取字段类型:", t.Field(i).Type,
		)
	}
	//根据索引去找内容
	fmt.Println(y.Field(0))
	fmt.Println(y.Field(1))
	//根据索引去找结构体内容,[]int{0}可以根据多层层级结构体找数据
	fmt.Println(y.FieldByIndex([]int{0}))
	fmt.Println(y.FieldByIndex([]int{1}))
	fmt.Println(y.FieldByIndex([]int{1, 0}))
	//根据名称去找结构体内容
	fmt.Println(y.FieldByName("Name"))

	//Kind是获取这个接口的底层类型
	ty := t.Kind()
	if ty == reflect.Struct {
		fmt.Println("我是Struct")
	} else if ty == reflect.Int {
		fmt.Println("我是Int")
	} else if ty == reflect.String {
		fmt.Println("我是String")
	}

}

func FanShe(v interface{}, o interface{}) {
	y := reflect.ValueOf(v)

	//Elem就是变量的原始类型
	p := y.Elem()
	fmt.Println(y, p)
	//根据Name找到字段并修改结构体的值,注意字段首字母必须大写!!否则不能被导出
	p.FieldByName("Name").SetString("啊对对对")
}