Go语言基础反射示例详解
程序员文章站
2022-06-10 15:07:47
目录概述语法一、基本操作二、修改目标对象三、动态调用方法总结示例概述在程序运行期对程序动态的进行访问和修改reflect godoc: https://golang.org/pkg/reflect/r...
概述
在程序运行期对程序动态的进行访问和修改
reflect godoc: https://golang.org/pkg/reflect/
reflect包有两个数据类型:
type:数据类型 【reflect.typeof():是获取type的方法】
value:值的类型【reflect.valueof():是获取value的方法】
语法
一、基本操作
获取变量类型
func typeof(i interface{}) type //type是interface{}的别名
例子
reflect.typeof(10) //int reflect.typeof(struct{ age int }{10}) //struct { age int }
获取变量的种类
reflect.typeof(struct{ age int }{10}).kind() //reflect.struct reflect.valueof("hello word").kind() //reflect.string
获取变量值
func valueof(i interface{}) value //value是struct {}别名
例子
reflect.valueof("hello word") //hello word reflect.valueof(struct{ age int }{10}) //{10}
二、修改目标对象
修改普通类型
str := "hello word" reflect.valueof(&str).elem().setstring("张三")
修改结构体
//第一步:valueof():传入一个变量的地址,返回是变量的地址 elem():返回的是变量的原始值 elem:=reflect.valueof(&变量名).elem() //第二步 fieldbyname():传入结构体字段名称 setstring():传入你要修改的变量值 elem.fieldbyname("name").setstring("李四")
//定义一个user结构体 type user struct { name string age int } user := user{name: "张三", age: 10} //elem() 获取user原始的值 elem := reflect.valueof(&user).elem() //fieldbyname() 通过name返回具有给定名称的结构字段 通过setstring 修改原始的值 elem.fieldbyname("name").setstring("李四") elem.fieldbyname("age").setint(18)
三、动态调用方法
无参方法
//methodbyname():传方法名,方法名必须大小 call():方法的形参 reflect.valueof(变量名).methodbyname(方法名).call([]reflect.value{}) reflect.valueof(变量名).methodbyname(方法名).call(make([]reflect.value, 0))
type user struct { name string `json:"name" name:"张三"` age int } func (_ user) say() { fmt.println("user 说话") } user := user{name: "张三", age: 10} reflect.valueof(&user).methodbyname("say").call([]reflect.value{}) reflect.valueof(user).methodbyname("say").call(make([]reflect.value, 0))
有参方法
reflect.valueof(变量名).methodbyname(方法名).call([]reflect.value{reflect.valueof("该说话了"), reflect.valueof(1)})
type user struct { name string `json:"name" name:"张三"` age int } func (_ user) say() { fmt.println("user 说话") } user := user{name: "张三", age: 10} reflect.valueof(user).methodbyname("saycontent").call([]reflect.value{reflect.valueof("该说话了"), reflect.valueof(1)})
总结
反射调用struct的方法必须是公有的
反射调用无参方法时必修传 nil 或者 []reflect.value{}
示例
package main import ( "fmt" "reflect" ) func main() { //1. 获取变量类型 fmt.println("获取变量类型") fmt.println(reflect.typeof(10)) //int fmt.println(reflect.typeof(10.0)) //float64 fmt.println(reflect.typeof(struct{ age int }{10})) //struct { age int } fmt.println(reflect.typeof(map[string]string{"a": "a"})) //map[string]string fmt.println("") //2. 获取变量值 fmt.println("获取变量值") fmt.println(reflect.valueof("hello word")) //hello word fmt.println(reflect.valueof(struct{ age int }{10})) //{10} fmt.println(reflect.typeof(struct{ age int }{10}).kind()) //struct //类型判断 if t := reflect.typeof(struct{ age int }{10}).kind(); t == reflect.struct { fmt.println("是结构体") } else { fmt.println("不是结构体") } //修改目标对象 str := "hello word" //普通变量修改 reflect.valueof(&str).elem().setstring("张三") fmt.println(str) //结构体变量修改 user := user{name: "张三", age: 10} //elem() 获取user原始的值 elem := reflect.valueof(&user).elem() //fieldbyname() 通过name返回具有给定名称的结构字段 通过setstring 修改原始的值 elem.fieldbyname("name").setstring("李四") elem.fieldbyname("age").setint(18) fmt.println(user) //获取结构体的标签的值 fmt.println(reflect.typeof(&user).elem().field(0).tag.get("name")) //调用无参方法 reflect.valueof(&user).methodbyname("say").call([]reflect.value{}) reflect.valueof(user).methodbyname("say").call(make([]reflect.value, 0)) //调用有参方法 reflect.valueof(user).methodbyname("saycontent").call([]reflect.value{reflect.valueof("该说话了"), reflect.valueof(1)}) //调用本地的方法 reflect.valueof(hello).call([]reflect.value{}) reflect.valueof(hello).call(nil) fmt.printf("%#v\n", reflect.typeof(user).field(0)) } func hello() { fmt.println("hello") } type person struct { name string } type user struct { person // //反射会将匿名字段作为一个独立字段来处理 name string `json:"name" name:"张三"` age int } func (_ user) say() { fmt.println("user 说话") } func (_ user) saycontent(content string, a int) { fmt.println("user", content, a) }
以上就是go语言基础反射示例详解的详细内容,更多关于go语言反射的资料请关注其它相关文章!
上一篇: CSS 一行代码实现头像与国旗的融合
下一篇: Java解决前端数据处理及乱码问题