Go语言基础之反射

50 阅读2分钟
# 变量的内在机制

Go语言中的变量是分为两部分的:

-   类型信息:预先定义好的元信息。
-   值信息:程序运行过程中可动态变化的

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

在Go语言的反射机制中,任何接口值都由是`一个具体类型``具体类型的值`两部分组成的
在Go语言中反射的相关功能由内置的reflect包提供,
任意接口值在反射中都可以理解为由`reflect.Type``reflect.Value`两部分组成,
并且reflect包提供了`reflect.TypeOf``reflect.ValueOf`两个函数来获取任意对象的Value和Type。

### type name和type kind
在反射中关于类型还划分为两种:`类型(Type)``种类(Kind)`。
因为在Go语言中我们可以使用type关键字构造很多自定义类型,
而`种类(Kind)`就是指底层的类型,但在反射中,当需要区分指针、结构体等大品种的类型时,就会用到`种类(Kind)`

## ValueOf
`reflect.ValueOf()`返回的是`reflect.Value`类型,其中包含了原始值的值信息。
`reflect.Value`与原始值之间可以互相转换

### 通过反射设置变量的值
想要在函数中通过反射修改变量的值,需要注意函数参数传递的是值拷贝,必须传递变量地址才能修改变量值。而反射中使用专有的`Elem()`方法来获取指针对应的值

`IsNil()`常被用于判断指针是否为空;`IsValid()`常被用于判定返回值是否有效(反射reflect.valueOf的方法)

# 结构体反射
任意值通过`reflect.TypeOf()`获得反射对象信息后,如果它的类型是结构体,可以通过反射值对象(`reflect.Type`)的`NumField()``Field()`方法获得结构体成员的详细信息