GO反射 | 青训营笔记

98 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记。

反射的定义

反射是指,计算机程序在运行时,可以访问、检测和修改它本身状态或行为的一种能力。用比喻来说,反射就是在程序运行时能够观察并且修改自己的行为。

GO语言提供了一种机制在运行时更新变量和检查他们的值、调用他们的方法。但是在编译时并不知道这些变量的具体类型,这成为“反射机制”。

在reflect包里定义了一个接口和一个机构体,即reflect.Type接口和reflect.Value机构体,她们提供很多函数来获取存储在借口里的类型信息。

  • reflect.Type接口主要提供关于类型相关的信息
  • reflect.Value结构体主要提供关于值相关的信息,可以获取甚至改变类型的值
func TypeOf(i interface()) Type
func ValueOf(i interface()) VAlue

TypeOf()函数用来提取一个接口中值的类型信息。由于它的输入参数是一个空的interface{},所以在调用此函数时,实参会先被转化为interface{}类型。这样,实参的类型信息、方法集、值信息都存储到interface{}变量里了。

反射的三大法则

  • 反射可以将“接口类型变量”转换为“反射类型对象”
  • 反射可以将“反射类型对象”转换为“接口类型变量”
  • 如果要修改“反射类型对象”,则其值必须是“可写的”

下面给出事例代码(其中之一)

package main

iomport (
    "fmt"
    "reflect"
 )
 fuc main() {
     var x float64 = 3.4
     fmt.Println("type:", reflect.TypeOf(x))
 }

反射中的一些常用方法

func (v Value) setBool(x bool)
func (v Value) setBytes(x []byte)
func (v Value) setFloat(x float64)
func (v Value) setInt(x int64)
func (v Value) setString(x int64)

反射的规则里需要注意以下几点

  • 不是接受变量指针创建的反射对象,是不具备“可写性”的
  • 是否具备“可写性”可使用CanSet()方法来得知
  • 创建反射对象时传入变量的是指针
  • 使用Elem()方法返回指针指向的数据