2021-08-06 来源:华纳网 责任编辑:railgun 人气:
核心提示:【谷雨课堂】Go实战 No.026 Go干货!轻松使用反射

知识点:

反射Reflect

本课内容:

大家好,欢迎来到谷雨课堂

 

本节我们讲一下反射中的干货

简单的说,反射就是动态的获取对象的各种信息

比如我们有一个结构,

我们想知道结构中都有哪些属性

有哪些可以调用的方法

进一步,修改属性的值及调用其中的方法及函数

这就是反射了

 

在各种语言中,反射是非常常用的,

在各种框架中,反射的使用尤为重要,

比如Go中的gin、beego、gozero等等

全部都使用到的反射

 

下面我们用代码来看一下最常用的反射的使用方法

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
package main
import ("fmt""reflect")
//定义一个结构体type User struct {  Name string  Age  int  Id   string}
//定义一个函数func (u *User) SayHello() {  fmt.Println("I'm " + u.Name + ", Id is " + u.Id + ". Nice to meet you! ")}
func main() {  tonydon := &User{"谷雨", 100, "123456"}  object := reflect.ValueOf(tonydon)  myref := object.Elem()  typeOfType := myref.Type()for i := 0; i < myref.NumField(); i++ {    field := myref.Field(i)    fmt.Printf("- %d. %s %s = %v \n", (i + 1), typeOfType.Field(i).Name, field.Type(), field.Interface())  }
  o1 := reflect.TypeOf(tonydon)for i := 0; i < o1.NumMethod(); i++ {    mt := o1.Method(i)    fmt.Printf("-- %d. %s  \n", i, mt.Name)  }
  fmt.Println("动态调用")  v := object.MethodByName("SayHello")  v.Call([]reflect.Value{})}

 

延伸阅读:

Go语言提供了一种机制在运行时更新和检查变量的值、调用变量的方法和变量支持的内在操作,但是在编译时并不知道这些变量的具体类型,这种机制被称为反射。反射也可以让我们将类型本身作为第一类的值类型处理。

 

反射是指在程序运行期对程序本身进行访问和修改的能力,程序在编译时变量被转换为内存地址,变量名不会被编译器写入到可执行部分,在运行程序时程序无法获取自身的信息。

 

支持反射的语言可以在程序编译期将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期获取类型的反射信息,并且有能力修改它们。

 

C/C++语言没有支持反射功能,只能通过 typeid 提供非常弱化的程序运行时类型信息;Java、C# 等语言都支持完整的反射功能;Lua、JavaScript 类动态语言,由于其本身的语法特性就可以让代码在运行期访问程序自身的值和类型信息,因此不需要反射系统。

 

Go语言程序的反射系统无法获取到一个可执行文件空间中或者是一个包中的所有类型信息,需要配合使用标准库中对应的词法、语法解析器和抽象语法树(AST)对源码进行扫描后获得这些信息。

 

Go语言提供了 reflect 包来访问程序的反射信息。

完整的源代码可以登录【华纳网】下载。

 

https://www.worldwarner.com/




 





免责声明:本文仅代表作者个人观点,与华纳网无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。