反射

反射

基本操作

func reflectTest01(b interface{}) {
	//通过反射获取传入的变量的type,kind,值
	//1. 先获取reflect.Type
	rType := reflect.TypeOf(b)
	fmt.Println(rType)
	//2. 先获取reflect.Value
	rVal := reflect.ValueOf(b)
	n2 := 2 + rVal.Int()
	fmt.Println(n2)
	fmt.Println(rVal)
	//将rVal转成interface{}
	iV := rVal.Interface()
	//将interface{}通过断言转成需要的类型
	num2 := iV.(int)
	fmt.Printf("num2=%v,num2 type=%T", num2, num2)

}
func main() {
	//反射的基本操作
	//定义int
	num := 100
	reflectTest01(num)

}

对结构体的反射

func reflectTest02(b interface{}) {
	//通过反射获取传入的变量的type,kind,值
	//1. 先获取reflect.Type
	rType := reflect.TypeOf(b)
	fmt.Println(rType)
	//2. 先获取reflect.Value
	rVal := reflect.ValueOf(b)

	// 获取变量对应的kind
	kind1:= rVal.Kind()
	kind2:= rType.Kind()
	fmt.Println(kind1,kind2)
	//将rVal转成interface{}
	iV := rVal.Interface()
	fmt.Printf("iv=%v,iv type=%T",iV,iV) //这里不能直接取到结构体的值需要断言
	//转成interface{},可以使用swtich的断言形式来做更加灵活
	stu,ok := iV.(Student) //
	if ok{
		fmt.Println(stu.Name)
	}

}

type Student struct {
	Name string
	Age  int
}

通过反射修改值


//通过反射修改num int的值和student的值
func reflectTest01(b interface{}) {

	rVal := reflect.ValueOf(b)
	fmt.Printf("rVal kind =%v", rVal.Kind())
	//通过Elem修改主函数的值
	rVal.Elem().SetInt(1)

}
func main() {
	num := 20
	fmt.Println(num)

}

反射案例


package main

import (
	"fmt"
	"reflect"
)

//定义一个monster方法
type Monster struct {
	Name  string  `json:"name"`
	Age   int     `json:"age"`
	Score float64 `json:"score"`
	Sex   string  `json:"sex"`
}

//输出s的值
func (s Monster) Pint() {
	fmt.Println("----start---")
	fmt.Println(s)
	fmt.Println("----end----")

}

//返回两个数的和
func (s Monster) GetSum(n1, n2 int) int {
	return n1 + n2

}

// 接收四个值,给Monster赋值
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{}) {
	//获取reflect.Type类型
	typ := reflect.TypeOf(a)
	//获取reflect.Value类型
	val := reflect.ValueOf(a)
	kd := val.Kind()
	//如果传入的不是struct,就退出
	if kd != reflect.Struct {
		fmt.Println("expect struct")
		return
	}
	//获取结构体有几个字段
	num := val.NumField()
	fmt.Printf("struct has %d fileds \n", num)
	//遍历结构体所有的字段
	for i := 0; i < num; i++ {
		fmt.Printf("Filed %d: 值为=%v \n", i, val.Field(i))
		//获取到struct标签,需要通过reflect.Type来获取tag标签的值
		tagVal := typ.Field(i).Tag.Get("json")
		if tagVal != "" {
			fmt.Printf("Field %d: tag为=%v\n", i, tagVal)

		}
	}
	numOfMethod := val.NumField()
	fmt.Printf("struct has %d method \n", numOfMethod)
	//var params[]reflect.Value
	val.Method(1).Call(nil)
	//调用结构体的第一个方法Method
	var params []reflect.Value
	params = append(params, reflect.ValueOf(10))
	params = append(params, reflect.ValueOf(40))
	res := val.Method(0).Call(params)//传入的参数[]reflect.Value
	fmt.Println("res=", res[0].Int())// 返回结果,返回的结果是[]reflect.Value


}
func main() {
	a :=Monster{Name: "喜喜",Age: 10,Score: 10.0,Sex: "男"}
	TestStruct(a)
}

  • 使用反射的方式来获取结构体的tag标签,遍历字段的值,修改字段的值

常量

const a int =1 或

const (
		a=1
		c="ccc"
	)
	fmt.Println(a,c)
posted @ 2021-02-06 23:16  小子,你摊上事了  阅读(56)  评论(0编辑  收藏  举报