千家信息网

Go语言中的反射怎么用

发表于:2024-10-24 作者:千家信息网编辑
千家信息网最后更新 2024年10月24日,这篇文章主要介绍Go语言中的反射怎么用,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!概述在程序运行期对程序动态的进行访问和修改reflect godoc: https://go
千家信息网最后更新 2024年10月24日Go语言中的反射怎么用

这篇文章主要介绍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)  //intreflect.TypeOf(struct{ age int }{10})  //struct { age int }

    获取变量的种类

    reflect.TypeOf(struct{ age int }{10}).Kind()  //reflect.Structreflect.ValueOf("hello word").Kind()  //reflect.String

    获取变量值

    func ValueOf(i interface{}) Value   //value是struct {}别名

    例子

    reflect.ValueOf("hello word")  //hello wordreflect.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 mainimport (        "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语言中的反射怎么用"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!

    0