1 、从接口变量到反射对象的转换,需要提到 reflect 包里很重要的两个方法
reflect.TypeOf(i) :获得接口值的类型
reflect.ValueOf(i):获得接口值的值
func main() {
var age interface{} = 25
fmt.Printf("原始接口变量的类型为 %T,值为 %v \n", age, age)
t := reflect.TypeOf(age)
v := reflect.ValueOf(age)
// 从接口变量到反射对象
fmt.Printf("从接口变量到反射对象:Type对象的类型为 %T \n", t)
fmt.Printf("从接口变量到反射对象:Value对象的类型为 %T \n", v)
}
2、从反射对象到接口变量的转换
func main() {
var age interface{} = 25
fmt.Printf("原始接口变量的类型为 %T,值为 %v \n", age, age)
t := reflect.TypeOf(age)
v := reflect.ValueOf(age)
// 从接口变量到反射对象
fmt.Printf("从接口变量到反射对象:Type对象的类型为 %T \n", t)
fmt.Printf("从接口变量到反射对象:Value对象的类型为 %T \n", v)
// 从反射对象到接口变量
i := v.Interface()
fmt.Printf("从反射对象到接口变量:新对象的类型为 %T 值为 %v \n", i, i)
}
最后转换后的对象,静态类型为 interface{} ,如果要转成最初的原始类型,需要再类型断言转换一下
i := v.Interface().(int)
3、settable (可设置性,或可写性)的概念
在反射的规则里
- 不是接收变量指针创建的反射对象,是不具备『可写性』的
- 是否具备『可写性』,可使用 CanSet() 来获取得知
- 对不具备『可写性』的对象进行修改,是没有意义的,也认为是不合法的,因此会报错。
func main() {
var name string = "abc"
v := reflect.ValueOf(name)
fmt.Println("可写性为:", v.CanSet())
}
要让反射对象具备可写性,需要注意两点
- 创建反射对象时传入变量的指针
- 使用 Elem()函数返回指针指向的数据
func main() {
var name string = "abc"
fmt.Println("真实世界里 name 的原始值为:", name)
v1 := reflect.ValueOf(&name)
v2 := v1.Elem()
v2.SetString("cba")
fmt.Println("通过反射对象进行更新后,真实世界里 name 变为:", name)
}
4、反射函数
1、Kind()
Kind() 方法返回对应的接口变量的基础类型
reflect.TypeOf(m).Kind()
reflect.ValueOf(m).Kind()
2、NumField() 和 Field()
func main() {
p := Person{"写代码的明哥", 27, "male"}
v := reflect.ValueOf(p)
fmt.Println("字段数:", v.NumField())
fmt.Println("第 1 个字段:", v.Field(0))
fmt.Println("第 2 个字段:", v.Field(1))
fmt.Println("第 3 个字段:", v.Field(2))
fmt.Println("==========================")
// 也可以这样来遍历
for i:=0;i<v.NumField();i++{
fmt.Printf("第 %d 个字段:%v \n", i+1, v.Field(i))
}
}
3、NumMethod() 和 Method()
func main() {
p := &Person{"写代码的明哥", 27, "male"}
t := reflect.TypeOf(p)
fmt.Println("方法数(可导出的):", t.NumMethod())
fmt.Println("第 1 个方法:", t.Method(0).Name)
fmt.Println("第 2 个方法:", t.Method(1).Name)
fmt.Println("==========================")
// 也可以这样来遍历
for i:=0;i<t.NumMethod();i++{
fmt.Printf("第 %d 个方法:%v \n", i+1, t.Method(i).Name)
}
}
网友评论