Go语言头秃之路(七)
更新系列
Go语言头秃之路(零)
Go语言头秃之路(一)
Go语言头秃之路(二)
Go语言头秃之路(三)
Go语言头秃之路(四)
Go语言头秃之路(五)
Go语言头秃之路(六)
反射
反射可以在运行时动态获取变量的各种信息- 应用场景:
- 当不知道接口调用哪个函数,根据传入参数在运行时确定调用的具体接口,这时需要对函数或方法反射。
eg: func bridge(funcPtr interface{}, args …interface{})
第一个参数funcPtr以接口形式传入函数指针,函数参数args以可变参数的形式传入,bridge函数中可以用反射来动态执行funcPtr函数。 - 对结构体序列化时, 如果结构体有指定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地址)
- 将反射转化为reflect.Value类型(reflect.ValueOf()),接着转为interface(reflect.Value.Interface()),然后通过断言获得原变量,最后进行赋值即可
- 使用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:定义两个函数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:使用反射操作任意结构体类型
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:使用反射创建并操作结构体
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)}
- 一些注意事项
- reflect.ValueOf.Method(i int)
这里的方法排序是按照方法名(ascii码)首字母顺序。
Go语言头秃之路(七)相关推荐
- Go语言头秃之路(零)
更新系列 Go语言头秃之路(一) Go语言头秃之路(二) Go语言头秃之路(三) Go语言头秃之路(四) Go语言头秃之路(五) Go语言头秃之路(六) Go语言头秃之路(七) 先导 指针 指针变量只 ...
- Go语言头秃之路(一)
更新系列 Go语言头秃之路(零) Go语言头秃之路(二) Go语言头秃之路(三) Go语言头秃之路(四) Go语言头秃之路(五) Go语言头秃之路(六) Go语言头秃之路(七) 各种基础语句 cons ...
- Go语言头秃之路(五)
更新系列 Go语言头秃之路(零) Go语言头秃之路(一) Go语言头秃之路(二) Go语言头秃之路(三) Go语言头秃之路(四) Go语言头秃之路(六) Go语言头秃之路(七) 文件操作 输入流:文件 ...
- Go语言头秃之路(三)
更新系列 Go语言头秃之路(零) Go语言头秃之路(一) Go语言头秃之路(二) Go语言头秃之路(四) Go语言头秃之路(五) Go语言头秃之路(六) Go语言头秃之路(七) 数组 定义语法:var ...
- lisp语言与python_又要头秃?2020 年七大 AI 编程语言大盘点
原标题:又要头秃?2020 年七大 AI 编程语言大盘点 本文讲述用于人工智能编程的顶级编程语言,AI工程师和相关从业者可从中选择适合他们项目所需要的语言,你Pick哪个呢? 作者 | Claire ...
- GO语言的进阶之路-协程和Channel
GO语言的进阶之路-协程和Channel 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 看过我之前几篇博客小伙伴可能对Golang语言的语法上了解的差不多了,但是,如果想要你的代码 ...
- python之路day5_Python语言之python之路笔记day19
本文主要向大家介绍了Python语言之python之路笔记day19,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助. 一.Django请求生命周期 对于所有的web框架来说本质就是 ...
- 51单片机C语言程序100例分析(1)IO+C语言+头文件
51单片机C语言程序100例分析(1)IO+C语言+头文件 \\\插播一条:文章末尾有惊喜哟~/// P1=0xfe;//P1=11111110B,即P1.0输出低电平} 分析:通过这短短的几行代码 ...
- JAVA自学之路 七:路线图明细
[原创 - 尚学堂科技 - 马士兵老师] JAVA自学之路 七:路线图明细 [转载请注明出处:http://www.bjsxt.com/zixue/zixuezhilu_7.html] 下面给出第二节 ...
最新文章
- HDU2018 母牛的故事
- 苹果开发着账号:个人、公司、企业账号的申请流程
- SQL 去除重复记录 只保留重复记录中的一条
- 计算机二级web题目(8.1)--综合选择题2
- 自动泊车算法中混合A*粗路径的MATLAB实现
- 关于numpy的一些矩阵运算——tile函数
- 全球第二和第四大航运公司加入物流巨头Maersk的区块链平台
- Gurobi软件求解线性规划问题(卜算学习记录)
- Android的gradle提示Could not resolve com.android.support:support-v4:26+.
- 计算机巧用剪纸做画册教案,大班剪纸教案 老虎
- echart柱状图横向_echarts 横向柱状图TOP10
- Layui同一个表单中放置两个按钮,提交问题
- 卡内基梅隆大学计算机专业介绍,卡内基梅隆大学计算机专业介绍 全美大学计算机专业榜首...
- 关于ttyS与ttySAC
- 动态规划的一般解题思路-详解
- BUUCTF:[UTCTF2020]sstv
- 【AI人工智能绘画 CV】Towards Robust Blind Face Restoration with Codebook Lookup Transformer
- 百度地图 JavaScript API
- 解决页面可以左右滑动但无法上下滑动(有坑))
- 3dsMax——开启捕捉之后锁定x/y/z轴