什么是反射
反射,嗯...,就是反着的意思呗,就是把东西反过来。
比如这样的一个很简单的代码。
var a int = 3 fmt.Println(a)
aintaint
这时候,就需要用到反射了。
示例代码
v := reflect.TypeOf(a) fmt.Println(v)
两次代码综合一块执行结果
aint
什么???你为我有什么用???,嗯。。。实话实说,用的不是太多,但是必须要会的。
反射(reflect包)
var a int = 3int3
reflect.Typereflect.Value
并且Go的提供了
reflect.TypeOfreflect.ValueOf
TypeOf
TypeOf
有一个这样的需求,定义一个函数,可以接收任意类型数据,通过反射打印变量类型。
示例代码
函数
func reflectType(x interface{}) { v := reflect.TypeOf(x) fmt.Printf("你传入的变量类型是:%v\n",v) }
main
func main() { var a int = 666 var b float64 = 3.14 var c string = "hello world" var d [3]int = [3]int{1,2,6} var e []int = []int{1,2,6,88} var f map[string]interface{} = map[string]interface{}{ "Name":"张三", "Age":18, } reflectType(a) reflectType(b) reflectType(c) reflectType(d) reflectType(e) reflectType(f) }
执行结果
reflect.TypeOf
TypeOf 的Name和Kind
这个是啥意思呢??这个在结构体中比较好体现。
TypeOf
示例代码
函数
func reflectType(x interface{}) { v := reflect.TypeOf(x) fmt.Printf("你传入的变量类型是:%v | Name:%v | Kind:%v\n", v, v.Name(), v.Kind()) }
结构体
type Student struct { Name string Age int }
main
func main() { var a int var b *int var c []int var d map[string]interface{} var e Student reflectType(a) reflectType(b) reflectType(c) reflectType(d) reflectType(e) }
执行结果
总结
经过对比,会发现几个特殊问题。
NameKindptr
NameKind
NameKindstruct
ValueOf
TypeOf
ValueOfValueOf
ValueOfTypeOfKind
需求:定义一个函数,可以接收任意类型,通过反射得出变量类型和变量值。
函数
func reflectType(x interface{}) { v := reflect.ValueOf(x) k := v.Kind() switch k { case reflect.Int: fmt.Printf("我是Int类型,我的值是%v\n",v.Int()) case reflect.Slice: fmt.Printf("我是切片类型,我的值是%v\n",v.Slice(1,2)) case reflect.Map: fmt.Printf("我是切片类型,我的值是%v\n",v.MapKeys()) //case :可以继续case下去 } }
main
func main() { var a int = 1 var c []int = []int{1, 5, 7, 19} var d map[string]interface{} = map[string]interface{}{ "Name": "你好", "Age": 18, } var e Student reflectType(a) reflectType(c) reflectType(d) reflectType(e) }
执行结果
通过反射设置值
反射还有一个用途,就是动态的修改变量值,可能你暂时体会不到,但是语法还是要学的。
Elem
示例代码
函数
func reflectSetValue(x interface{}) { v := reflect.ValueOf(x) //kind也必须是Elem调用 var k = v.Elem().Kind() switch k { case reflect.Int: //反射修改必须通过Elem v.Elem().SetInt(200) } }
main
func main() { var a int = 10 fmt.Printf("a的值:%v\n", a) //反射修改值传入的必须是地址 reflectSetValue(&a) fmt.Printf("a的值:%v\n", a) }
执行结果
总结
TypeOfTypeOf的Name和KindValueOf通过反射设置值
KindTypeValueOfTypeOfValueOf
反射这一块,可能不是那么好理解,一定要多多下功夫!坚持!!