培训首页  >  web前端新闻  >  兄弟连区块链培训教程之反射简介

兄弟连区块链培训教程之反射简介

[2018-09-20 17:34:55] 浏览量:87 来源:

北京兄弟连IT

  很多人喜欢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("设置为其他值...")

        }

    }

 

}

  • 软件开发
  • 软件测试
  • 数据库
  • Web前端
  • 大数据
  • 人工智能
  • 零基础
  • 有HTML基础
  • 有PHP基础
  • 有C语言基础
  • 有JAVA基础
  • 其他计算机语言基础
  • 周末班
  • 全日制白班
  • 随到随学