11.反射
反射初识
反射是指在程序运行期间对程序本身进行访问和修改的能力
TypeOf
使用reflect.TypeOf()函数可以获得任意值的类型对象
package main
import (
"fmt"
"reflect"
)
// reflect demo
func reflectType(x interface{}) {
// 此时不知道别人调用这个函数的时候会传进来什么类型的变量
// 方式1. 通过类型断言
// 方式2. 借助反射
obj := reflect.TypeOf(x)
// fmt.Printf("obj: %v\n", obj)
fmt.Println(obj, obj.Name(), obj.Kind()) // .name()类型,.kind()种类
fmt.Printf("%T\n", obj) // *reflect.rtype reflect内置类型的一个指针
}
func main() {
var a float32 = 1.23
reflectType(a)
}
在反射中,数组、切片、map、指针等类型的变量,.Name返回都是空
ValueOf
reflect.ValueOf()拿到原始值
func reflectValue (x interface{}){
v:=reflect.ValueOf(x)
fmt.Printf("%v, %T\n", v, v)
}
func main(){
aa:= 100
}
结构体反射
| 方法 | 说明 |
|---|---|
| Field(i int) StructField | 根据索引,返回索引对应的结构体字段的信息。 |
| NumField() int | 返回结构体成员字段数量。 |
| FieldByName(name string) (StructField, bool) | 根据给定字符串返回字符串对应的结构体字段的信息。 |
| FieldByIndex(index []int) StructField | 多层成员访问时,根据 []int 提供的每个结构体的字段索引,返回字段的信息。 |
| FieldByNameFunc(match func(string) bool) (StructField,bool) | 根据传入的匹配函数匹配需要的字段。 |
| NumMethod() int | 返回该类型的方法集中方法的数目 |
| Method(int) Method | 返回该类型方法集中的第i个方法 |
| MethodByName(string)(Method, bool) | 根据方法名返回该类型方法集中的方法 |
package main
import (
"fmt"
"reflect"
)
// 结构体反射
type student struct {
Name string `json:"name" ini:"s_name"`
Score int `json:"score" ini:"s_score"`
}
func main() {
stu1 := student{
Name: "小王子",
Score: 49,
}
// 通过反射获取结构体中的所有字段信息
t := reflect.TypeOf(stu1)
fmt.Printf("t.Name(): %v ", t.Name())
fmt.Printf("t.Kind(): %v\n", t.Kind())
// 遍历结构体变量的所有字段
for i := 0; i < t.NumField(); i++ {
// 根据结构体字段的索引去获取字段
filedObj := t.Field(i)
fmt.Printf("filedObj.Name: %v\n", filedObj.Name)
fmt.Printf("filedObj.Type: %v\n", filedObj.Type)
fmt.Printf("filedObj.Tag: %v\n", filedObj.Tag)
fmt.Println(filedObj.Tag.Get("json"), filedObj.Tag.Get("ini"))
}
// 根据名字去取结构体中的字段
filed, ok := t.FieldByName("Score")
if ok {
fmt.Printf("name:%v type:%v tag:%v", filed.Name, filed.Type, filed.Tag)
}
}
反射能让我们写出更加灵活的代码,但不应被滥用:
- 基于反射的代码极其脆弱,反射中的错误会在真正运行的时候才会引发panic,那很可能是在代码写完的很长时间以后
- 大量的反射代码通常难以理解
- 反射的性能低下,基于反射的代码通常比正常代码运行速度慢一到两个量级

浙公网安备 33010602011771号