# 变量的内在机制
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()`方法获得结构体成员的详细信息