了解反射本质,本文就介绍了反射的基础内容。
一个变量的本质是一个数据地址和一种数据类型,然后根据这两个变量进行操作即反射;
代码如下(示例):
type Teacher struct {
Topic string
Age int
}
func main() {
//s := new(Student)
s := &Student{Name: "222"}
fmt.Println(reflect.TypeOf(s)) // ----> *main.Student
fmt.Println(reflect.TypeOf(s).Elem()) // ----> main.Student
fmt.Println(reflect.TypeOf(*s)) // ----> main.Student
v := reflect.ValueOf(s).Elem() // (依靠不安全的操作存储器对齐来强制转换)方法将运行时类型和变量转换为反射类型和变量
v.Field(0).SetString("66")
// 最后,调用 Interface ()方法将变量从反射状态转换回运行时状态。
fmt.Printf("%#v\n", v.Interface()) // ----> main.Student{Name:"66", Age:0}
t := Teacher{}
fmt.Println(reflect.TypeOf(&t).Elem())
//fmt.Println(reflect.TypeOf(t).Elem()) panic
field, _ := reflect.TypeOf(&t).Elem().FieldByName("Topic")
fmt.Println("field.PkgPath--->", field.PkgPath)
fmt.Println("field--->", field)
fmt.Println(reflect.TypeOf(&t).Elem().FieldByName("Age"))
fmt.Println(reflect.TypeOf(&t))
fmt.Println(reflect.TypeOf(t).Field(0))
fmt.Println(reflect.TypeOf(t).Field(0))
fmt.Println(reflect.TypeOf(t).Name())
fmt.Println(reflect.TypeOf(t).PkgPath())
fmt.Println(reflect.TypeOf(t).FieldByName("Topic"))
// 通过指针反射操作 内部实现 *(*string)(v.ptr) = x
// 即需要通过地址来完成操作
reflect.ValueOf(&t).Elem().Field(0).SetString("99999")
fmt.Println("field Value SetString --->", t)
reflect.ValueOf(t).Field(1)
fmt.Println("field Value get --->", reflect.ValueOf(t).Field(0))
}
注意反射都是指针方向的操作,所以操作时不要使用copy值,而应该使用指针类型;总之反射=op(指针,type); 而运行时变量==interface==address+type的具体体现;
以上就是今天要讲的内容,本文仅仅简单介绍了反射的使用