39 反射(Reflection)

Go是一门静态类型语言,绝大多数情况下,变量的类型在编译时就是已知的。

一种例外是接口类型,尤其是空接口interface{}

空接口是一个动态类型,跟Java或C#里的Object类似。

在编译时,我们无法分辨接口类型的底层值是一个int还是string

标准库中的Reflect包使得我们能够在运行时处理这些动态值。我们可以:

  • 检查动态值的类型

  • 枚举struct的字段

  • 为字段设置值

  • 在运行时创建一个新值

用于在运行时检查接口值的类型的相关语言级功能是类型转换类型断言

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var v interface{} = 4
	var reflectVal reflect.Value = reflect.ValueOf(v)

	var typ reflect.Type = reflectVal.Type()
	fmt.Printf("Type '%s' of size: %d bytes\n", typ.Name(), typ.Size())
	if typ.Kind() == reflect.Int {
		fmt.Printf("v contains value of type int\n")
	}
}

// -----OUTPUT-------
// Type 'int' of size: 8 bytes
// v contains value of type int

上述代码是反射的基本操作:

  • 从一个空接口(interface{})类型的值开始

  • 使用reflect.ValueOf(v interface{})去得到reflect.Value类型的变量,它表示关于该值的信息

  • 使用reflect.Value去检查值的类型、值是否为nil、设置新的值

反射有几个实际用途

最后更新于