Go语言反射 | 青训营笔记

81 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 18 天

一、本堂课重点内容

本堂课的知识要点有哪些?

  • Go语言反射

二、详细知识点介绍

本堂课介绍了哪些知识点?

Go语言反射

  1. 所谓反射是指Go语言程序运行时的内存变量状态的反馈,可用标准库中的反射包reflect完成内存变量的动态反射。反射的内容主要是变量的类型以及变量的值以及数据类型的方法等相关的信息。

  2. 反射的主要作用在于处理那些需要动态确定参数类型和数量的函数,如fmt包中的打印函数、扫描函数等。

  3. 由于Go语言类型形态极为复杂多样,不同数据类型支持的方法也不同,如果使用不好reflect,很容易导致panic,所以建议谨慎使用。

  4. 要使用反射,首先需要引入反射包:

    import "reflect"
    
  5. 类型反射函数是Go语言编程中使用比较多的一个函数,其使用格式如下:

    t := reflect.TypeOf(i)
    

    其中i为任意类型的变量,ti的值的类型。

  6. 值反射与类型反射一样,都是基于内存变量的,变量的数据类型不同,其值的形式也不同,反射值使用下述格式:

    v := reflect.ValueOf(i)
    

    i为任意内存变量,v为该变量在内存中的值。

  7. 结构体往往带有多个字段,如果需要获得每个字段的信息,就需要循环处理每个字段,reflect包为字段处理提供了丰富的方法。如果结构体类型带有多种方法,则可以用索引及循环的方法获得每个方法的返回值。

  8. TypeOf函数能反射结构体的字段名称,而要反射字段的值则需要ValueOf函数,用for循环遍历每一个字段,打印输出每一个字段名及字段的值。值反射能返回结构体字段数量NumField,根据这个值就可以遍历全部字段,获得字段的值及tag。

  9. ValueOf()函数的参数亦可以是指针变量,作用于指针变量的反射value,有些方法可以用来设置变量的值。

  10. 结构体除了字段的属性能被反射出来以外,添加在其上面的方法也可以被反射出来,还能被执行。可以使用以下格式反射方法:

    reflect.ValueOf(x).Method(i int).Call([]reflect.Value)
    

    reflect.ValueOf(x).MethodbyName(s string).Call([]reflect.Value)
    
  11. 方法的输入参数及返回值均为[]reflect.Value类型切片,因此,参数输入之前及方法调用返回之后,都要进行相关的转换。

  12. 反射具体方法并调用它,建议使用MethodByName方法,清晰明了。如果用Methodindex)容易出问题,因为方法列表并不按照其编程时出现的顺序排序,而是按照字母顺序,因而容易忽略次序而出错。

  13. 上述程序中定义了一个结构体及两个方法。方法的输入输出参数都用[]reflect.Value类型的切片来表示。每个参数都需要采用reflect.ValueOf反射出来,然后再赋值给切片。返回值也一样,为[]reflect.Value切片,要获得其元素的值需要采用reflect.Value再反射回来。

三、引用参考

我参考了哪些外部博客/笔记/文章?