兄弟连区块链培训教程之反射简介
很多人喜欢Go语言,其实是因为Go语言有其独特的语言属性在支撑着其在编程语言界的发展,今天兄弟连Go语言+区块链培训老师给大家介绍一下关于Go语言之反射简介,下面我们一起来看一下吧。( )
反射概述
· 通常的程序逻辑是:编码时先写好剧本,运行时按照写好的剧本演
· 何时创建一个什么实例,给哪个属性赋什么值,然后调用它的哪个方法都毫厘不差
· 但能否在运行时动态地生成“剧本”呢?
· 根据具体的业务需要见机行事,动态地生成一个不知道具体类型会是什么的实例,动态地访问一个无法提前预知的属性或方法
· 答案是可以的,这便引出了今天的主角——反射
应用场景举例:导出商品列表到Excel
· 需求是:不管用户在界面上看到什么商品列表,当它捅一下导出按钮,就将该商品的所有属性和值写出为文件;
· 本例的难点是:我们无法预知用户会选择导出什么类型的商品数据、它有哪些属性,也就无法相应地去创建Excel数据表的列(读写Excel有相应的库,你也可以选择写出为文本文件、写出到数据库表中等等)
· 因为商品的种类太多,如果用正射去做,那么有多少商品类型我们就要写多少个switch或if分支,然后在每一个分支里根据当前分支的具体商品类型去构造相应的Excel数据列,这显然是蹩脚并且很难维护和扩展的
· 而通过反射来做就易如反掌了,管你来的是什么商品实例,立即动态解析得到其类别、所有属性名值,然后根据属性名去创建Excel的列,根据属性值去做数据的填充和写入
定义结构体
type Human struct {
Name string "姓名"
Age int "年龄"
}
func (h *Human) GetName() string {
fmt.Println("GetName called",h.Name)
return h.Name
}
func (h *Human) SetName(name string) {
fmt.Println("SetName called:", name)
h.Name = name
}
func (h *Human) Eat(food string, grams int) (power int) {
fmt.Println("Eat called:", food, grams)
return 5 * grams
}
反射功能一览
func main() {
//创建对象(在实际开发中可以是任意未知类型)
h := Human{"bill", 60}
//获取任意对象的类型和值
getObjTypeValue(h)
//获得任意对象的所有属性
getObjFields(h)
//获取任意对象的所有方法
getObjMethods(&h)
//修改对象任意属性的值
modifyFieldValue(&h)
//动态调用对象的任意方法
callMethods(&h)
fmt.Println("after:h=", h)
}
获取任意对象的类型和值
func getObjTypeValue(obj interface{}) {
oType := reflect.TypeOf(obj)
oKind := oType.Kind()
fmt.Println(oType, oKind)
oValue := reflect.ValueOf(obj)
fmt.Println(oValue)}
获得任意对象的所有属性
func getObjFields(obj interface{}) {
oType := reflect.TypeOf(obj)
oValue := reflect.ValueOf(obj)
fieldsCount := oType.NumField()
for i := 0; i < fieldsCount; i++ {
//从对象值中获取第i个属性的值,进而值的“正射”形式
fValue := oValue.Field(i).Interface()
structField := oType.Field(i)
fmt.Println(structField.Name, structField.Type, structField.Tag, fValue)
}
}
获取任意对象的所有方法
func getObjMethods(obj interface{}) {
oType := reflect.TypeOf(obj)
fmt.Println(oType.NumMethod())
for i := 0; i < oType.NumMethod(); i++ {
method := oType.Method(i)
fmt.Println(method.Name, method.Type)
}
}
修改对象任意属性的值
func modifyFieldValue(objPtr interface{}) {
//得到【指针的Value】
oPtrValue := reflect.ValueOf(objPtr)
//得到【指针所指向的值(结构体)的Value】
oValue := oPtrValue.Elem()
fmt.Println(oValue)
//遍历所有属性的值
for i := 0; i < oValue.NumField(); i++ {
//根据序号拿到【属性的Value】
fValue := oValue.Field(i)
//拿到属性值的原生类型
fKind := fValue.Kind()
//fmt.Println(fKind)
//根据不同的原生类型设置为不同的值
switch fKind {
case reflect.String:
fValue.SetString("张全蛋")
case reflect.Int:
fValue.SetInt(99)
case reflect.Bool:
fValue.SetBool(false)
default:
fmt.Println("设置为其他值...")
}
}
}
网上报名
新闻资讯
更多>>-
兄弟连“因材施教搭建桥梁”计划正式启动
2018-06-14
-
兄弟连PHP培训:高薪就业才是硬道理
2018-06-14
-
兄弟连北京安卓培训:万元高薪班级爆满
2018-06-14
-
25W高薪挑战安卓 零基础培训首选兄弟连
2018-06-14
-
兄弟连PHP教程发布 海量资源应有尽有
2018-06-14