Golang反射机制
反射概念:
反射是一种让程序检查自身结构的能力
特殊的静态类型interface
interface类型是一种特殊的类型,它代表方法集合,可以存放实现了其方法的值。
反射三定律
反射可以将interface类型变量转换成反射对象
import (
"fmt"
"reflect"
)
func main() {
var x float64
x = 7.66
t := reflect.TypeOf(x)
fmt.Println("Type:", t)
v := reflect.ValueOf(x)
fmt.Println("Value:", v)
}
反射是针对interface变量的,其中TypeOf()和ValueOf()接收的参数都是interface类型的,即上述代码中的x的值是被转换了interface传入的。
反射可以将反射对象还原成interface对象
import (
"fmt"
"reflect"
)
func main() {
var e int
e = 10
v := reflect.ValueOf(e)
var y int = v.Interface().(int)
fmt.Println("value:", y)
fmt.Println("the type of y :", reflect.TypeOf(y))
}
对象e转换成反射对象v,v又通过Interface()接口转换成interface对象,interface对象又通过int断言获取int类型的值
反射对象可修改,value值必须是可设置的
通过反射可以将interface类型变量转换成反射对象,可以使用该反射对象设置其持有的值。
首先,尝试修改反射对象的value
import (
"fmt"
"reflect"
)
func main() {
var new_x float64
new_x = 2.5
v := reflect.ValueOf(new_x)
v.SetFloat(25.23)
fmt.Println(v)
}
运行结果:
goroutine 1 [running]:
reflect.flag.mustBeAssignableSlow(0x14000066ed8?)
/usr/local/go/src/reflect/value.go:260 +0x74
reflect.flag.mustBeAssignable(...)
/usr/local/go/src/reflect/value.go:247
reflect.Value.SetFloat({0x10028aee0?, 0x1400011c008?, 0x14000066f28?}, 0x40393ae147ae147b)
/usr/local/go/src/reflect/value.go:2219 +0x40
main.main()
/Users/kol/go/src/GoSJ/ch10-reflect/reflect_3.go:12 +0xec
上例中,传入reflect.ValueOf()函数的其实是x的值,而非x本身。即通过v修改其值是无法影响x的,也即是无效 的修改,所以golang会报错。
想到此处,即可明白,如果构建v时使用x的地址就可实现修改了,但此时v代表的是指针地址,我们要设置的是指针所 指向的内容,也即我们想要修改的是 *v 。 那怎么通过v修改x的值呢?
reflect.Value 提供了 Elem() 方法,可以获得指针向指向的 value 。
修改如下:
import (
"fmt"
"reflect"
)
func main() {
var new_x float64
new_x = 2.5
v := reflect.ValueOf(&new_x)
v.Elem().SetFloat(25.25)
fmt.Println("new_x:", v.Elem().Interface())
}
输出如下:
new_x: 25.25

浙公网安备 33010602011771号