反射
# 方法和类型的反射
反射是用程序检查其所拥有的结构,尤其是类型的一种能力。反射可以在运行时检查类型和变量,例如它的大小、方法和动态的调用这些方法。这对于没有源代码的包尤其有用。这是一个强大的工具,除非真得有必要,否则应当避免使用或小心使用。
变量的最基本信息就是类型和值:反射包的Type用来表示一个Go类型,反射包的Value为Go提供了反射接口。
两个简单的函数,reflect.TypeOf 和 reflect.ValueOf, 返回被检查对象的类型和值。例如,x 被定义为: var x float = 3.4, 那么reflect.Typeof(x) 返回float64, reflect.ValueOf(x) 返回《float64 Value》
实际上,反射是通过检查一个接口的值,变量首先被转换为空接口。 反射可以从接口值反射到对象,也可以从对象反射回接口值。
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
fmt.Println("type:", reflect.TypeOf(x))
v := reflect.ValueOf(x)
fmt.Println("value:", v)
fmt.Println("type:", v.Type())
fmt.Println("kind:", v.Kind())
fmt.Println("value:", v.Float())
fmt.Println(v.Interface())
y := v.Interface().(float64)
fmt.Println(y)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 通过反射修改(设置)值
当 v := reflect.ValueOf(x)函数通过传递一个x拷贝创建了v, 那么v的改变并不能更改原始的x。要想v得更改能作用到x,那就必须传递x的地址 v = reflect.ValueOf(&x)。 通过Type() 我们看到v现在的类型是*float, 并且仍然是不可设置的。
上次更新: 2023/01/11