反射
反射提供了一种机制能够在运行时检测类型和变量,动态调用它们的方法,而不需要在编译时就知道这些变量的具体类型。golang中使用reflect
包来实现反射。
反射虽然提供很多额外的能力,但是反射的总体性能比较低,在要求性能的场景应该尽量避免使用反射。
反射包中reflect.TypeOf
能获取类型信息对于的类型是Type
,reflect.ValueOf
能获值信息对于的类型是Value
。
func TypeOf(i interface{}) Type
func ValueOf(i interface{}) Value
使用TypeOf
反射一个变量的时候,我们可以获取其类型的相关信息。
type Stu struct {
Name string `json:"name"`
age int
}
func (s Stu) Say() {
fmt.Println(s.Name)
}
s := Stu{"wida", 0}
t := reflect.TypeOf(s)
fmt.Println(t.Kind()) //类型为 struct
for i := 0; i < t.NumField(); i++ { //反射所有的字段
fmt.Println(t.Field(i)) //t.Field 返回 StructField 这里结构体标签的信息 Name字段的标签 `json:"name"`可以在这边获取
}
for i := 0; i < t.NumMethod(); i++ { //反射所有的方法
fmt.Println(t.Method(i))
}
使用ValueOf
反射一个变量的是,我们可以获取s变量值的信息。
type Stu struct {
Name string `json:"name"`
age int
}
func (s Stu) Say() {
fmt.Println(s.Name)
}
s := Stu{"wida", 0}
t := reflect.ValueOf(s)
fmt.Println(t.Kind()) //类型为 struct
for i := 0; i < t.NumField(); i++ { //反射所有的字段
fmt.Println(t.Field(i)) //这边返回的是Value
}
for i := 0; i < t.NumMethod(); i++ { //反射所有的方法
fmt.Println(t.Method(i))
}
可以通过Value
修改变量的值
x := 2
d := reflect.ValueOf(&x).Elem() // Elem返回Value的指针类型
d.SetInt(3)
fmt.Println(x) // "3"