Go的反射建立在两种类型上:Type
和Value
。它们都定义在reflect
包中。Type
代表Go的一个类型,是一个接口类型。Value
代表Go的一个值,是一个结构体类型。
type Type interface {
// methods...
}
type Value struct {
// unexported fields...
}
我们可以通过reflect.TypeOf()
和reflect.ValueOf()
函数来获取任何对象的类型和值:
t := reflect.TypeOf(3) // a reflect.Type
fmt.Println(t) // "int"
v := reflect.ValueOf(3) // a reflect.Value
fmt.Println(v) // "3"
fmt.Printf("%v\n", v) // "3"
reflect.Value
获取值我们可以通过reflect.Value
的方法来获取其底层的值。比如,我们可以用Int()
方法获取其表示的int值:
v := reflect.ValueOf(3) // a reflect.Value
x := v.Int() // an int64
fmt.Println(x) // "3"
reflect.Value
reflect.Value
的CanSet()
方法会返回一个布尔值,表明我们是否可以修改这个值。要修改一个值,首先需要确保它是可寻址的,可以通过使用指针或者reflect.Value
的Elem()
方法来获取原始值。
var x float64 = 3.4
v := reflect.ValueOf(&x)
fmt.Println("type:", v.Type())
fmt.Println("can set:", v.Elem().CanSet())
在Go中,反射是一个强大的工具,可以帮助我们进行动态编程。但是,需要注意的是,反射的使用应该保持谨慎,因为过度使用反射可能会导致代码难以阅读和维护,同时也可能带来性能开销。