社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
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
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!