golang中可以使用reflect包进行反射编程,常用的是使用reflect进行变量类型的判断:
reflect.TypeOf 返回变量类型 (reflect.Type枚举类型)
reflect.ValueOf返回变量的值 (reflect.Value)
通过kind来判断变量类型
变量类型判断:
输出结果:
使用reflect.TypeOf可以获得interface的类型,同样也可以通过reflect.ValueOf().Type()来获得interface的类型:
输出结果:
利用反射编程编写灵活的代码
按名字访问结果的成员
reflect.ValueOf(*e).FieldByName("Name")
上面使用反射机制访问struct结构体e中的属性变量Name。
按名字访问结构体的方法
reflect.ValueOf(e).MethodByName("UpdateAge").Call([]reflect.Value{reflect.ValueOf(1)})
上面的代码通过反射机制调用了结构体e的UpdateAge方法,并通过Call向UpdateAge方法传递参数。
运行结果:
可以发现在使用reflect调用Student的方法前后,Student的属性发生了改变。
上面的代码中,我们使用reflect.TypeOf().FieldName()获取到Struct的某个属性的reflect.StructField,然后通过reflect.StructField.Tag可以获得Struct定义中的Tag属性。reflect.StructField.Tag在Golang内置的json解析中,被用来解析数据结果和Struct属性名之间的映射关系。
【注意】reflect.ValueOf()和reflect.TypeOf()都有FieldByName的方法,但是两者获得的Struct属性是不一样的:
// 获得的是struct的属性值reflect.ValueOf(struct).FileByName(fieldName)
// 获得的是struct的属性特征reflect.TypeOf(struct).FieldByName(fieldName)
我们可以从这个属性特征中获得属性数据类型、属性Struct的Tag信息等等。