因为本人没有强类型语言的经验,所以之前也没怎么接触过反射的概念。我在维基百科上搜索了一下,具体解释如下:在计算机科学中,反射式编程(英语:reflectiveprogramming)或反射(英语:reflection)是指在运行时(runtime)可以被访问、检测和修改的计算机程序.其自身状态或行为的能力。比喻地说,反射是程序在运行时“观察”和修改其行为的能力。go中的反射也有这个作用。在程序运行过程中,可以获得变量的类型和值的信息,然后进行访问或修改。在go语言中,有一个内置的reflect包,用来获取一个变量的类型(type)和值(value)。对应的方法分别是reflect.TypeOf()和reflect.ValueOf()。反射类型的TypeOf方法会返回变量的类型对象,在类型对象下可以获取到变量的类型和类型。import("fmt""reflect")funcmain(){//定义一个int类型的变量variint=1//获取变量的类型对象vartypeOfNum=reflect.TypeOf(i)//输出类型和类型typeOfNumName=typeOfNum.Name()typeOfNumKind=typeOfNum.Kind()fmt.Printf("name:%s,kind:%s",typeOfNumName,typeOfNumKind)}可以看到type和kind都是int。Type和Kindtype表示定义变量时指定的类型,可以反映type关键字定义的类型,kind是变量的最终类型。说起来可能有些苍白,我们直接上代码吧。typenumint//定义一个num类型的变量varinum=1vartypeOfNum=reflect.TypeOf(i)可以看到类型是num,类型是int。对于一些引用类型的变量,比如切片、函数、结构体,kind可以准确反映底层类型。funcprintTypeOf(typeOfreflect.Type){fmt.Printf("name:%s,kind:%s\n",typeOf.Name(),typeOf.Kind())}typePersonstruct{}typeIntSlice[]intfuncmain(){vara=IntSlice{}varb=Person{}printTypeOf(reflect.TypeOf(a))printTypeOf(reflect.TypeOf(b))}面对匿名结构或匿名函数,其类型值将返回空。funcmain(){vara=struct{}{}printTypeOf(reflect.TypeOf(a))}反射值ValueOf方法,可以得到一个变量的值。vari=3.1415926vars="欢迎关注我的公众号:《自然觉醒笔记本》"可以获取变量的类型,根据其类型调用相应的方法获取变量的真实值。vari=100varv=reflect.ValueOf(i)fmt.Println(v.Int())//如果value是Int类型,可以通过Int方法获取具体值fmt.Println(v.Kind())修改值,通过反射获取变量本身的值对象是可以修改的。首先,获取反射值时,不能直接获取变量的反射值,必须先获取其指针的值对象。vari=100varv=reflect.ValueOf(&i)//获取变量i的指针的值对象fmt.Println(v.Kind(),v)取出指针的值对象后,不能立即赋值,因为此时得到的是变量的地址。如果要赋值,需要先调用Elem方法,取出具体的元素,再进行赋值。vari=100varv=reflect.ValueOf(&i)//获取变量i指针的值对象vare=v.Elem()e.SetInt(500)//修改元素值fmt.Println(e.Kind(),i)前面介绍了值对象和结构体,可以通过反射获取变量的值,结构体也是如此。typePersonstruct{namestringageintgenderstringaddressstring}varp=Person{"Shenfq",25,"Male","湖南长沙"}varv=reflect.ValueOf(p)fmt.Println(v.Kind(),v)反射值对象还提供some方法,专门用来获取结构体成员的信息。NumField()NumField()可以得到结构成员的具体个数。varp=Person{"Shenfq",25,"Male","湖南长沙"}varv=reflect.ValueOf(p)fmt.Println("Person结构体的成员个数:",v.NumField())Field()Field()可以得到结构体指定索引位置的成员的反映值。varp=Person{"Shenfq",25,"男","湖南长沙"}varv=reflect.ValueOf(p)varnum=v.NumField()fori:=0;i
