欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Go语言基础反射示例详解

程序员文章站 2022-03-06 13:04:51
目录概述语法一、基本操作二、修改目标对象三、动态调用方法总结示例概述在程序运行期对程序动态的进行访问和修改reflect godoc: https://golang.org/pkg/reflect/r...

Go语言基础反射示例详解

概述

在程序运行期对程序动态的进行访问和修改

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语言反射的资料请关注其它相关文章!