zoukankan      html  css  js  c++  java
  • golang之反射

    反射基本介绍

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

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

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

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

    反射重要的函数和概念

      1)reflect.TypeOf(变量名),获取变量的类型,返回reflect.Type类型

      2)reflect.ValueOf(变量名),获取变量的值,返回reflect.Value类型,reflect.Value是一个结构体类型。通过reflect.Value,可以获取到关于该变量的很多信息

      3)变量、interface{}和reflect.Value是可以相互转换的,这点在实际开发中,会经常使用到。

        interface{}  ——>  reflect.Value:

          rVal := reflect.ValueOf(b)

        reflect.Value  ——>  interface{}:

          iVal := rVal.Interface()

        interface{}  ——>  原来的变量(类型断言):

          v := iVal.(Stu)

    快速入门案例

      对基本数据类型

    func reflectTest01(b interface{}) {
        // 1.获取到reflect.Type
        rType := reflect.TypeOf(b)
        fmt.Println("rType = ", rType)
    
        // 2.获取到reflect.Value
        rVal := reflect.ValueOf(b)
        fmt.Printf("rVal = %v, rVal = %T
    ", rVal, rVal)
    
        n2 := 2 + rVal.Int()
        fmt.Println("n2 = ", n2)
    
        // 将 rVal 转换成 interface{}
        iV := rVal.Interface()
        // 通过类型断言转成需要的类型
        num2 := iV.(int)
        fmt.Printf("num2 = %v, num2 = %T
    ", num2, num2)
    }

      对结构体

    func reflectTest02(b interface{}) {                                   
        rType := reflect.TypeOf(b)                                        
        fmt.Println(rType)                                                
                                                                          
        rVal := reflect.ValueOf(b)                                        
        iV := rVal.Interface()                                            
        fmt.Printf("iv=%v	iv type=%T
    ", iV, iV)                         
                                                                          
        stu, ok := iV.(Student)                                           
        if ok {                                                           
            fmt.Println("stu.Name=", stu.Name)                            
        }                                                                 
    }                                                                     

     反射的注意事项

      1)reflect.Value.kind,获取变量的类别,返回的是一个常量

      2)Type是类型,kind是类别,可能相同,也可能不相同

        比如:var num int = 10   num的Type是int,Kind也是int

              var stu Student    stu的Type是包名.Student,Kind是struct

       3)通过反射可以让变量在interface{}和Reflect.Value之间相互转换:

          变量 <——> interface{} <——> reflect.Value

      4)使用反射的方式来获取变量的值(并返回对应的类型),要求数据类型匹配,比如x是int,那么就应该使用reflect.Value(x).Int(),而不能使用其它的,否则报painc

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

    func reflectTest(b interface{}) {
        rVal := reflect.ValueOf(b)
        rVal.Elem().SetInt(20)
    }
    
    func main() {
        var num = 10
        reflectTest(&num)
        fmt.Println(num)
    }

      6)reflect.Elem()的理解:  

    	var i int = 3
    	var p *int = &i
    	fmt.Println(p, i)
    
    	v := reflect.ValueOf(p)
    	fmt.Println(v)
    	fmt.Println(v.Interface()) // This is the p pointer
    
    	fmt.Println(v.Elem().Interface()) // This is i's value: 3
    

      

    人生就是要不断折腾
  • 相关阅读:
    用Python作GIS:择菜篇
    【嵌入式开发技术之串口】Linux下串口主机程序
    1033,2052 是什么意思?
    Telnet协议详解
    生活情景英语:英语国家生存英语精选
    windows下搭建iphone开发环境
    开公司的流程
    解决某物流企业二维码打印问题
    数字黑洞
    InnoSetup 打包代码 检测.netFramework
  • 原文地址:https://www.cnblogs.com/xiangxiaolin/p/12315461.html
Copyright © 2011-2022 走看看