更新系列

Go语言头秃之路(零)
Go语言头秃之路(一)
Go语言头秃之路(二)
Go语言头秃之路(三)
Go语言头秃之路(四)
Go语言头秃之路(五)
Go语言头秃之路(六)


  • 反射
    反射可以在运行时动态获取变量的各种信息

    • 应用场景:
    1. 当不知道接口调用哪个函数,根据传入参数在运行时确定调用的具体接口,这时需要对函数或方法反射。
      eg: func bridge(funcPtr interface{}, args …interface{})
      第一个参数funcPtr以接口形式传入函数指针,函数参数args以可变参数的形式传入,bridge函数中可以用反射来动态执行funcPtr函数。
    2. 对结构体序列化时, 如果结构体有指定tag, 也会使用到反射生成对应的字符串。
    • reflect包实现了运行时反射,允许程序操作任意类型的对象。
      常用方法:
      reflect.TypeOf() 返回 reflect.Type类型
      reflect.ValueOf() 返回 reflect.Value类型
      具体使用:
    func test(i interface{}) {// 1. interface{} -> reflect.Value类型rVal := reflect.ValueOf(b)// 2. 将reflect.Value类型转回原来变量类型// reflect.Value类型 -> interface{}iVal := rVal.Interface()// interface{} -> 原来的变量类型 (断言)v := iVal.(Person)
    }
    

    • 需要想要修改反射对应变量值,需要reflect.ValueOf()接收地址,然后使用reflat.Value.Elem().Set…方法
    i := 3
    rVal := reflect.ValueOf(&i)
    fmt.Println(rVal.Kind())   // ptr
    // Elem() 相当于取出指针指向地址的值进行修改
    fmt.Println(rVal.Elem().Int())   // 3
    rVal.Elem().SetInt(6)
    fmt.Println(i)  // 6
    
    • 修改struct反射中元素值的方法(需要传struct地址)
    1. 将反射转化为reflect.Value类型(reflect.ValueOf()),接着转为interface(reflect.Value.Interface()),然后通过断言获得原变量,最后进行赋值即可
    2. 使用Elem() + Field() + Set…(xx)方法
      两种方法饭粒:

      func TestStruct2(i interface{}) {//获取reflect.Value 类型val := reflect.ValueOf(i)// 方法1.// inter := val.Interface()// astruct := inter.(*Monster)// astruct.Name = "黄鼠狼"// 方法2. ele := val.Elem()ele.Field(0).SetInt(500)ele.Field(1).SetString("黄鼠狼")// fmt.Printf("%v, type: %T", ele, ele)
      }
      
    • 一些小程序
    1. 反射应用1:定义两个函数test1和test2, 定义一个适配器函数用作统一处理接口

      func TestReflectFunc(t *testing.T)  {call1 := func(v1 int, v2 int) {t.Log(v1, v2)}call2 := func(v1 int, v2 int, s string) {t.Log(v1, v2, s)}var (function reflect.ValueinValue []reflect.Valuen int)bridge := func(call interface{}, args...interface{}) {n = len(args)inValue = make([]reflect.Value, n)for i := 0; i<n; i++ {inValue[i] = reflect.ValueOf(args[i])}function = reflect.ValueOf(call)function.Call(inValue)}
      }
      
    2. 反射应用2:使用反射操作任意结构体类型
      type user struct {UserId stringName string
      }
      func TestReflectStruct(t *testing.T)  {var (model *usersv reflect.Value)model = &user{}sv = reflect.ValueOf(model)t.Log("reflect.ValueOf", sv.kind().String())sv = sv.Elem()t.Log("reflect.ValueOf.Elem", sv.Kind().string())sv.FieldByName("UserId").SetString("333333")sv.FieldByName("Name").SetString("Fone")t.Log("model", model)
      }
      
    3. 反射应用3:使用反射创建并操作结构体
      func TestReflectStructPtr(t *testing.T) {var (model *userst reflect.Typeelem reflect.Value)st = reflect.TypeOf(model) // 获取类型*usert.Log("reflect.TypeOf", st.Kind().string()) // ptrst = st.Elem()  // st 指向的类型t.Log("reflect.TypeOf.Elem", st.Kind().String()) // structelem = reflect.New(st)  // New返回一个Value类型值,该值持有一个指向类型为typ的新申请的零值的指针t.Log("reflect.New", elem.Kind().string())  // ptrt.Log("reflect.New.Elem", elem.Elem().kind().String())  // struct// model 就是创建的user结构体变量(实例)model = elem.Interface().(*user)  // model是*user, 它的指向和elem是一样的elem = elem.Elem()  // 取得elem指向的值elem.FieldByName("UserId").SetString("007")   // 赋值elem.FieldByName("Name").SetString("Fone")   // 赋值t.Log("model model.Name", model, model.Name)}
      
    • 一些注意事项
    1. reflect.ValueOf.Method(i int)
      这里的方法排序是按照方法名(ascii码)首字母顺序。

Go语言头秃之路(七)相关推荐

  1. Go语言头秃之路(零)

    更新系列 Go语言头秃之路(一) Go语言头秃之路(二) Go语言头秃之路(三) Go语言头秃之路(四) Go语言头秃之路(五) Go语言头秃之路(六) Go语言头秃之路(七) 先导 指针 指针变量只 ...

  2. Go语言头秃之路(一)

    更新系列 Go语言头秃之路(零) Go语言头秃之路(二) Go语言头秃之路(三) Go语言头秃之路(四) Go语言头秃之路(五) Go语言头秃之路(六) Go语言头秃之路(七) 各种基础语句 cons ...

  3. Go语言头秃之路(五)

    更新系列 Go语言头秃之路(零) Go语言头秃之路(一) Go语言头秃之路(二) Go语言头秃之路(三) Go语言头秃之路(四) Go语言头秃之路(六) Go语言头秃之路(七) 文件操作 输入流:文件 ...

  4. Go语言头秃之路(三)

    更新系列 Go语言头秃之路(零) Go语言头秃之路(一) Go语言头秃之路(二) Go语言头秃之路(四) Go语言头秃之路(五) Go语言头秃之路(六) Go语言头秃之路(七) 数组 定义语法:var ...

  5. lisp语言与python_又要头秃?2020 年七大 AI 编程语言大盘点

    原标题:又要头秃?2020 年七大 AI 编程语言大盘点 本文讲述用于人工智能编程的顶级编程语言,AI工程师和相关从业者可从中选择适合他们项目所需要的语言,你Pick哪个呢? 作者 | Claire ...

  6. GO语言的进阶之路-协程和Channel

    GO语言的进阶之路-协程和Channel 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 看过我之前几篇博客小伙伴可能对Golang语言的语法上了解的差不多了,但是,如果想要你的代码 ...

  7. python之路day5_Python语言之python之路笔记day19

    本文主要向大家介绍了Python语言之python之路笔记day19,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助. 一.Django请求生命周期 对于所有的web框架来说本质就是 ...

  8. 51单片机C语言程序100例分析(1)IO+C语言+头文件

    51单片机C语言程序100例分析(1)IO+C语言+头文件 \\\插播一条:文章末尾有惊喜哟~///  P1=0xfe;//P1=11111110B,即P1.0输出低电平} 分析:通过这短短的几行代码 ...

  9. JAVA自学之路 七:路线图明细

    [原创 - 尚学堂科技 - 马士兵老师] JAVA自学之路 七:路线图明细 [转载请注明出处:http://www.bjsxt.com/zixue/zixuezhilu_7.html] 下面给出第二节 ...

最新文章

  1. HDU2018 母牛的故事
  2. 苹果开发着账号:个人、公司、企业账号的申请流程
  3. SQL 去除重复记录 只保留重复记录中的一条
  4. 计算机二级web题目(8.1)--综合选择题2
  5. 自动泊车算法中混合A*粗路径的MATLAB实现
  6. 关于numpy的一些矩阵运算——tile函数
  7. 全球第二和第四大航运公司加入物流巨头Maersk的区块链平台
  8. Gurobi软件求解线性规划问题(卜算学习记录)
  9. Android的gradle提示Could not resolve com.android.support:support-v4:26+.
  10. 计算机巧用剪纸做画册教案,大班剪纸教案 老虎
  11. echart柱状图横向_echarts 横向柱状图TOP10
  12. Layui同一个表单中放置两个按钮,提交问题
  13. 卡内基梅隆大学计算机专业介绍,卡内基梅隆大学计算机专业介绍 全美大学计算机专业榜首...
  14. 关于ttyS与ttySAC
  15. 动态规划的一般解题思路-详解
  16. BUUCTF:[UTCTF2020]sstv
  17. 【AI人工智能绘画 CV】Towards Robust Blind Face Restoration with Codebook Lookup Transformer
  18. 百度地图 JavaScript API
  19. 解决页面可以左右滑动但无法上下滑动(有坑))
  20. 3dsMax——开启捕捉之后锁定x/y/z轴

热门文章

  1. Words for Windows
  2. Ros智能小车麦克纳姆轮、橡胶轮的加紧固办法、轮子紧固不脱离
  3. 计算机三级网络技术笔记(选择题)
  4. 英语小短信,值得学习
  5. C语言标准,ANSI C,ISO C,GNU C
  6. 基于java的springboot失物招领系统毕业设计springboot开题报告
  7. 人工智能教程 - 前言
  8. 甲骨文:“狂妄”的秘诀
  9. 2021年专升本考试政策什么时候发布?发布前该准备什么?
  10. WJ01-涂鸦版参数