在Go语言中反射的相关功能由内置的reflect包提供,任意接口值在反射中都可以理解为由reflect.Type和reflect.Value两部分组成, 并且reflect包提供了reflect.TypeOf和reflect.ValueOf两个函数来获取任意对象的Value和Type。 1.TypeOf typeof的对象中可以使用两个方法 t.name t.kind 其中t.name是自定义命名的名字,而t.kind是底层的类型 比如 type cat struct{} 这个name就是cat 而 kind就是struct 2.ValueOf reflect.ValueOf()返回的是reflect.Value类型,其中包含了原始值的值信息。reflect.Value与原始值之间可以互相转换。 v对象同样也有kind,但没有name kind对象可以取到值的类型并转换成对应的原始值 例如: func reflectValue(x interface{}) { v := reflect.ValueOf(x) k := v.Kind() switch k { case reflect.Int64: // v.Int()从反射中获取整型的原始值,然后通过int64()强制类型转换 fmt.Printf("type is int64, value is %d\n", int64(v.Int())) case reflect.Float32: // v.Float()从反射中获取浮点型的原始值,然后通过float32()强制类型转换 fmt.Printf("type is float32, value is %f\n", float32(v.Float())) case reflect.Float64: // v.Float()从反射中获取浮点型的原始值,然后通过float64()强制类型转换 fmt.Printf("type is float64, value is %f\n", float64(v.Float())) } } 通过反射设置变量的值 想要在函数中通过反射修改变量的值,需要注意函数参数传递的是值拷贝,必须传递变量地址才能修改变量值。而反射中使用专有的Elem()方法来获取指针对应的值。 比如 func reflectSetValue1(x interface{}) { v := reflect.ValueOf(x) if v.Kind() == reflect.Int64 { v.SetInt(200) //修改的是副本,reflect包会引发panic } } func reflectSetValue2(x interface{}) { v := reflect.ValueOf(x) // 反射中使用 Elem()方法获取指针对应的值 if v.Elem().Kind() == reflect.Int64 { v.Elem().SetInt(200) } } func main() { var a int64 = 100 // reflectSetValue1(a) //panic: reflect: reflect.Value.SetInt using unaddressable value reflectSetValue2(&a) //传递a的指针,修改原始值 fmt.Println(a) } func (v Value) IsNil() bool 报告v持有的值是否为nil。v持有的值的分类必须是通道、函数、接口、映射、指针、切片之一;否则IsNil函数会导致panic。 func (v Value) IsValid() bool 返回v是否持有一个值。如果v是Value零值会返回假,此时v除了IsValid、String、Kind之外的方法都会导致panic。 func main() { // *int类型空指针 var a *int fmt.Println("var a *int IsNil:", reflect.ValueOf(a).IsNil()) // nil值 fmt.Println("nil IsValid:", reflect.ValueOf(nil).IsValid()) // 实例化一个匿名结构体 b := struct{}{} // 尝试从结构体中查找"abc"字段 fmt.Println("不存在的结构体成员:", reflect.ValueOf(b).FieldByName("abc").IsValid()) // 尝试从结构体中查找"abc"方法 fmt.Println("不存在的结构体方法:", reflect.ValueOf(b).MethodByName("abc").IsValid()) // map c := map[string]int{} // 尝试从map中查找一个不存在的键 fmt.Println("map中不存在的键:", reflect.ValueOf(c).MapIndex(reflect.ValueOf("娜扎")).IsValid()) } 结构体反射 type student struct { Name string `json:"name"` Score int `json:"score"` } 结构体划分为几部分 stu1 := student{ Name: "小王子", Score: 90, } 比如这个结构体,对typeof这个函数来说返回的对象是t 其中两个方法 是 t.name (student)和 t.kind(struct) t.NumField()会返回结构体中的字段数目是2 所以有: 遍历所有结构体字段: for i:=0;i