golang中的反射 - Go语言中文社区

golang中的反射


1、golang中的反射机制

1.1、反射的基本介绍
在这里插入图片描述
在这里插入图片描述
1.2、反射的应用场景
在这里插入图片描述
1.3、反射重要的函数和概念

在这里插入图片描述
在这里插入图片描述
1.4、反射入门说明
在这里插入图片描述

package main

import (
	"fmt"
	"reflect"
)

/**
 *  @Description:反射的简单应用
 *  @Author: guai
 *  @Date:2020/2/27 19:16
**/

//通过反射获取传入的变量
func reflectPractice(inter interface{}) {
	//1、获取reflectType
	rType := reflect.TypeOf(inter)
	fmt.Println("rType:", rType)

	//2、获取reflect.Value
	rVal := reflect.ValueOf(inter)
	fmt.Println("rVal+1:", rVal.Int()+1)

	//3、将rVal转成interface{}
	interRef := rVal.Interface()
	//使用断言将interface类型转化为需要的类型
	num := interRef.(int)
	fmt.Println("num+1:", num+1)
}

func reflectPractice1(inter interface{}) {

	//1、获取inter的类型  
	//kind获取的类型是golang中的类型如自定义的结构体的skind 是struct 
	rType := reflect.TypeOf(inter)
	rKind := (reflect.ValueOf(inter)).Kind()
	fmt.Println("rType: ", rType)
	fmt.Println("rKind:", rKind)

	//2、获取inter的值
	rVal := reflect.ValueOf(inter)
	fmt.Println("rVal:", rVal)

	//3、将rVal转化为interface{}
	interRef := rVal.Interface()
	fmt.Printf("interRef=%v interRef type=%Tn", interRef, interRef)

	//使用断言将interRef转为需要的类型
	//使用带检测的断言
	stu, ok := interRef.(student)
	if ok {
		fmt.Println("stu.name=", stu.name)
	}

}

type student struct {
	name string
	age  int
}

func main() {

	//1、测试对基本类型的反射操作
	var num int = 100
	reflectPractice(num)

	//2、测试对结构体的反射操作
	stu := student{"guao", 12}
	reflectPractice1(stu)
}

结果:
在这里插入图片描述
注意:
在这里插入图片描述
1.5、
使用reflect.Value.Elem()的使用

func main(){
	var num1 int = 100
	fn := reflect.ValueOf(&num1)
	//fn.Elem() 用于获取指针指向的变量 类似于 *fn
	fn.Elem().SetInt(200)
	fmt.Println("num1:", num1)
}

结果:
在这里插入图片描述

1.6、反射课堂练习:

package main

import (
	"fmt"
	"reflect"
)

/**
 *  @Description: 反射最佳实践
 *  @Author: guai
 *  @Date:2020/2/27 20:34
**/

type monster struct {
	name string `json:"name"`
	age  int    `json:"age"`
	sum  int    `json:"sum"`
}

func (s monster) GetSum(n1 int, n2 int) int {
	return n1 + n2
}
func (s monster) Set(vals ...interface{}) {
	s.name = vals[0].(string)
	s.age = vals[1].(int)
	s.sum = vals[2].(int)
}
func (s monster) PrintM() {
	fmt.Println("monster:", s)
}

func TestStruct(inter interface{}) {
	//获取a的type
	interType := reflect.TypeOf(inter)
	val := reflect.ValueOf(inter)
	kd := val.Kind()
	if kd != reflect.Struct {
		fmt.Println("expect stuct")
		return
	}
	//通过 .NumField() 获取结构体有几个字段
	num := val.NumField()
	fmt.Println("struct num:", num)
	for i := 0; i < num; i++ {
		//通过 .Field() 获取字段中的值
		fmt.Printf("Field %d 的值为:%vn", i, val.Field(i))

		//获取struct的标签 通过reflect.ype.Field().Tag.Get() 获取tag值
		tagVal := interType.Field(i).Tag.Get("json")
		if tagVal != "" {
			fmt.Printf("Field %d 的tag为%vn", i, tagVal)
		}
	}

	//或取结构体中方法的个数  注意方法只能获取结构体方法名开头大写的方法个数
	//即只能获取可以在外包访问的方法的个数
	numOfMethod := val.NumMethod()
	fmt.Printf("struct has %d methodsn", numOfMethod)

	//方法的排序默认是按照函数名排序的 (ASII码)
	//调用结构体的第二个方法
	val.Method(1).Call(nil)

	//定义参数 反射类型
	var params []reflect.Value
	params = append(params, reflect.ValueOf(10))
	params = append(params, reflect.ValueOf(10))
	//调用结构体的第一个方法  返回结果为reflect.Value()类型
	res := val.Method(0).Call(params)
	fmt.Println("res:", res[0].Int())
}
func main() {
	mons := monster{"guai", 12, 12}
	TestStruct(mons)
}

结果:
在这里插入图片描述
部分图片来自 Go语言-尚硅谷_韩顺平_Go语言核心编程.pdf如需我删除,可以留言或者私聊哟
磕头ing

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_44373940/article/details/104542991
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢