反射

反射提供了一种机制能够在运行时检测类型和变量,动态调用它们的方法,而不需要在编译时就知道这些变量的具体类型。golang中使用reflect包来实现反射。 反射虽然提供很多额外的能力,但是反射的总体性能比较低,在要求性能的场景应该尽量避免使用反射。

反射包中reflect.TypeOf能获取类型信息对于的类型是Typereflect.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"