(四十五)golang--反射

(四十五)golang--反射,第1张

概述反射基本介绍: (1)反射可以在运行时动态获取变量的各种信息,比如变量的类型、类别; (2)如果是结构体变量,还可以获取结构体本身的信息(包括结构体字段、方法); (3)通过反射,可以修改变量的值,可

反射基本介绍:@H_301_5@

(1)反射可以在运行时动态获取变量的各种信息,比如变量的类型、类别;@H_301_5@

(2)如果是结构体变量,还可以获取结构体本身的信息(包括结构体字段、方法);@H_301_5@

(3)通过反射,可以修改变量的值,可以调用关联的方法;@H_301_5@

(4)使用反射,需要import "reflect:"@H_301_5@

变量--空接口--relect.Value之间的转换关系:@H_301_5@

@H_301_5@@H_301_5@

int变量与反射变量之间的转换:@H_301_5@

package mainimport (    "fmt"    reflect")func reflectTest(b interface{}) {    rTyp := reflect.TypeOf(b)    fmt.Printf(rTyp=%v,type=%T\n,rTyp,rTyp)    rVal := reflect.ValueOf(b)    fmt.Printf(rVal=%v,rVal,rVal)    iVal := rVal.Interface()    num2 := iVal.(int)    fmt.Printf(num2=%v,num2,num2)}func main() {    var num int = 100    reflectTest(num)}

@H_301_5@@H_301_5@

 结构体变量与反射变量之间的转换:@H_301_5@

type student struct {    name string    age  }func reflectTest02(b  rVal.Interface()    stu2 := iVal.(student)    fmt.Printf(stu2=%v,stu2,stu2)    fmt.Printf(name:%v,age:%v student{        name: tom20

@H_301_5@@H_301_5@

反射注意事项和使用细节:
(1)reflect.Vale.Kind,获取变量的类别,返回的是一个常量;@H_301_5@

@H_301_5@@H_301_5@

(2)Type是类型,Kind是类别,Type和Kind可能是相同的,也可能是不同的;@H_301_5@

比如:var num int=10的type是Int,Kind也是int@H_301_5@

     var stu Student, stu的rype是pkg1.Student,Kind是struct@H_301_5@

(3)通过反射介意让变量在interface{}和reflect.Value之间相互转换;@H_301_5@

(4)使用反射的方式来获取变量的值,要求数据类型匹配;@H_301_5@

(5)通过反射来修改变量,注意当使用SetXxx方法来设置需要通过对指针类型来完成,这样才能改变传入变量的值,同时需要使用到reflect.Value.Elem()方法;即rVal.Elem().SetInt(20)@H_301_5@

具体实践;@H_301_5@

使用反射来遍历结构体的字段,并调用结构体的方法,并获取结构体标签的值。@H_301_5@

)type monster  {    name  string `Json:name`    Age   int    `Json:monster_age`    score float32    Sex   }func (m monster) Print() {    fmt.Println(----strat----)    fmt.Println()    fmt.Println(----end----)}func (m monster) GetSum(n1,n2 int)  {    return n1 + n2}func (m monster) Set(name string,age int,score float32,sex ) {    m.name = name    m.Age = age    m.score = score    m.Sex = sex}func testStruct(b {}) {    //获得类型    rtyp := reflect.TypeOf(b)    获得值    rval := reflect.ValueOf(b)    获得类别    kd := rval.Kind()    如果kd不是指针类型且rval.Elem()不是结构体类别    if kd != reflect.Ptr && rval.Elem().Kind() == reflect.Struct {        fmt.Println(expect struct)        return    }    获取结构体有几个字段    num := rval.Elem().NumFIEld()    fmt.Printf(struct has %d fIElds\n遍历每个字段    for i := 0; i < num; i++ {        输出该字段的值        fmt.Printf(fIEld %d:值为=%v\n获取该字段的Json标签        tagval := rtyp.Elem().FIEld(i).Tag.Get(Json如果标签不为空,则打印出标签        if tagval != "" {            fmt.Printf(fIEld %d:tag为=%v\n0).SetString(孙悟空)    获取结构体有几个方法    numOfMethod := rval.Elem().NumMethod()    fmt.Printf(struct has %d methods\n获取第二个方法,函数的顺序是按首字母的ACSII进行排序的,所以这里第二个方法是Print    rval.Elem().Method(1).Call(nil)    定义一个reflect.Value切片    var params []reflect.Value    添加两个整型    params = append(params,reflect.ValueOf(10))    40调用第一个方法,并传入参数(注意参数类型是reflect.Value切片)    res := rval.Elem().Method(0).Call(注意res是一个切片,里面只有一个值    fmt.Println(res=",res[0].Int())}func main() {    var a monster = monster{        name:  40020.9a)    fmt.Println(a)}

要在反射中修改结构体的字段的值,必须传入的是地址,并且在反射中使用.Elem().SetXxx()@H_301_5@

@H_301_5@@H_301_5@

具体实践2:通过反射完成适配器@H_301_5@

func main() {    test1 := func(v1 ) {        fmt.Printf(v1=%d,v2=%d\n= func(call interface{},args ...{}) {        获取参数长度        n := len(args)        定义参数切片        params := make([]reflect.Value,n)        将参数存入到切片中        0; i < n; i++ {            params[i] = reflect.ValueOf(args[i])        }         for i := 0; i < n; i++ {             fmt.Println(args[i])         }        获取函数名        function := reflect.ValueOf(call)        将参数传给函数,并调用函数        function.Call()    }    brIDge(test1,1,2)    brIDge(test2,1)">2,1)">test2)}

运行结果:@H_301_5@

@H_301_5@@H_301_5@

具体实践3:通过反射 *** 作任意结构体类型@H_301_5@

type user  {    UserID     name   }func testReflectStruct() {    var (        model *user        sv    reflect.Value    )    model = &user{}    sv = reflect.ValueOf(model)    这里是指针类别    fmt.Println(sv.Kind().String())    sv = sv.Elem()    这里是结构体类别    fmt.Println(sv.Kind().String())    sv.FIEldByname(UserID").SetString(1)    sv.FIEldByname(name)    fmt.Println(model)}

@H_301_5@@H_301_5@

 @H_301_5@

 @H_301_5@ 总结

以上是内存溢出为你收集整理的(四十五)golang--反射全部内容,希望文章能够帮你解决(四十五)golang--反射所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1262168.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存