go学习笔记——go语言的反射机制

 1.简单介绍

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

        在 Go 语言中,反射是指在运行时动态地查看和修改对象的能力。Go 语言提供了一个 reflect 包,该包提供了一套机制,用于操作任意类型的对象。

反射可以实现以下几个功能:

  1. 动态类型转换:可以将一个值转换为另一个类型的值;
  2. 动态调用方法和函数:可以根据方法和函数名,在运行时动态地调用它们;
  3. 动态修改变量值:可以在运行时修改变量的值,包括私有成员变量的值;
  4. 动态创建实例:可以在运行时根据类型创建实例对象。

2.反射的核心

        Go语言中的反射是由 reflect 包提供支持的,它定义了两个重要的类型 Type 和 Value 任意接口值在反射中都可以理解为由 reflect.Type 和 reflect.Value 两部分组成,并且 reflect 包提供了 reflect.TypeOf 和 reflect.ValueOf 两个函数来获取任意对象的 Value 和 Type。

        在Go语言中使用这个反射机制之前需要导入reflect包: import reflect

        下面举一个代码例子介绍:

func main() {
	var a int16
	a = 10
	fmt.Println(reflect.TypeOf(a))
	fmt.Println(reflect.ValueOf(a))

	type MyInt int
	var b MyInt
	b = 20
	fmt.Println(reflect.TypeOf(b))
	fmt.Println(reflect.TypeOf(b).Kind())
}

        运行结果:

        上述实例代码主要介绍了reflect包中的reflect.TypeOf()、reflect.ValueOf()和Kind()的使用 

3.Type和Kind

       在 Go 语言的反射机制中,Type和Kind是两个重要的概念。

        Type是反射包中的一个类型,表示一个变量的类型信息。使用reflect.TypeOf()可以获取到一个变量的类型反射对象。

        Kind是Type的一部分,它表示一个变量的底层类型。使用reflect.ValueOf().Kind()可以获取到一个变量的底层类型。比如如果一个变量的类型是指针,则其底层类型是指向的类型。需要注意的是,Kind并不等同于Type,因为它只表示底层类型,而不包括其他的类型信息(比如数组长度、结构体字段等)。

下面是一个示例代码,演示了 `Type` 和 `Kind` 的用法和区别:

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var a int = 10
    t := reflect.TypeOf(a) // 获取 a 的类型反射对象
    k := t.Kind()          // 获取 a 的底层类型
    fmt.Println("a's Type:", t)
    fmt.Println("a's Kind:", k)

    var b *int = &a
    t = reflect.TypeOf(b)  // 获取 b 的类型反射对象
    k = t.Kind()           // 获取 b 的底层类型
    fmt.Println("b's Type:", t)
    fmt.Println("b's Kind:", k)
}

        在上面的代码中,我们定义了两个变量 a和b。我们使用reflect.TypeOf()获取a和b的类型反射对象,并使用 t.Kind() 获取它们的底层类型。最后,我们分别输出了 a 和 b 的类型和底层类型。

        需要注意的是,对于结构体和数组等复合类型,Kind 的返回值只表示其底层基础类型。如果需要获取详细的类型信息,可以使用 Type 来进行操作。

猜你喜欢

转载自blog.csdn.net/m0_53891399/article/details/130934844