golang中的反射
反射操作普通变量
package main import ( "fmt" "reflect" ) func main(){ a := 1 //reflect.TypeOf获取类型 fmt.Println(reflect.TypeOf(a)) //int //查看占的字节 fmt.Println(reflect.TypeOf(a).Size())//8 //TypeOf获取的是reflect.Type类型,可以转化成字符串 fmt.Println(reflect.TypeOf(a).Name() == "int") //true fmt.Println(reflect.TypeOf(a).String() == "int") //true //对于一个interface{},我们便可以通过这种方式来判断到底是什么类型 func(val interface{}){ switch t:=reflect.TypeOf(val).String();t { case "int": fmt.Println("val的类型为int") case "string": fmt.Println("val的类型为string") case "int32": fmt.Println("val的类型为int32") case "[]int": fallthrough case "[]string": fmt.Println("val的类型为切片") } }([]int{}) //val的类型为切片 b := 'x' //获取的是reflect.Value类型,注意此时是没有办法比较的 fmt.Println(reflect.ValueOf(b)) //120 /* //获取相应的值,但你要提前知道类型,然后调用相应的方法 fmt.Println(reflect.ValueOf(b).Int()) fmt.Println(reflect.ValueOf(b).String()) fmt.Println(reflect.ValueOf(b).Float()) */ //不过也可以使用interface进行转化,会自动推断出具有真正类型的值 fmt.Println(reflect.ValueOf(b).Interface() == 'x') //true //使用kind()或者Type()也可以获取值类型,再转换成String fmt.Println(reflect.ValueOf(b).Kind().String() == "int32")//true fmt.Println(reflect.ValueOf(b).Type().String() == "int32")//true //如何设置一个值 name:="mashiro" //这里必须要传递指针进去,因为golang是值传递,传递值的话会单独拷贝一份。Elem()是为了得到变量的指针 val := reflect.ValueOf(&name).Elem() fmt.Println(val.CanSet()) //true val.SetString("satori") fmt.Println(name)//satori }
反射操作结构体
package main import ( "fmt" "reflect" ) type Girl struct { Name string Age int Gender string Length int } //给结构体定义几个方法 func (g Girl)Info(){ fmt.Println("info") } func (g Girl)Info1(){ fmt.Println("info1") } func (g Girl)Info2(){ fmt.Println("info2") } func main(){ //先来如何获取结构体的类型 g := Girl{"satori",16,"f",155} //我们之前看用Kind()和Type()获取的类型都是一样的,但那只是针对于int string之类的 //当换成结构体的时候,我们看到,kind()的范围比较大,得到的是一个struct,而Type()得到的是具体的struct类型 fmt.Println(reflect.ValueOf(g).Kind()) //struct fmt.Println(reflect.ValueOf(g).Type()) //main.girl //所以我们也可以判断是不是结构体,怎么判断呢? //注意使用Kind()得到的是一个reflect.Value类型,因此要是用reflect.Struct判断 fmt.Println(reflect.ValueOf(g).Kind() == reflect.Struct) //true //如果使用字符串判断的话,那么可以转化一下 fmt.Println(reflect.ValueOf(g).Kind().String() == "struct")//true //使用TypeOf(),Name()和String()获取的都是字符串,但是Name()不包含main fmt.Println(reflect.TypeOf(g).Name() == "girl") //true fmt.Println(reflect.TypeOf(g).String() == "main.girl") //true //再来看看获取结构体内部元素的属性 //如何获取结构体的字段的数量 fmt.Println(reflect.ValueOf(g).NumField(), reflect.TypeOf(g).NumField()) //4 4 //如何获取结构体的方法的数量,注意方法名必须要大写,否则检测不到 fmt.Println(reflect.ValueOf(g).NumMethod(), reflect.TypeOf(g).NumMethod()) //3 3 //调用方法,只能通过ValueOf,Call中必须传入[]reflect.Value类型 var params []reflect.Value reflect.ValueOf(g).Method(0).Call(params) //info reflect.ValueOf(g).Method(1).Call(params) //info1 reflect.ValueOf(g).Method(2).Call(params) //info2 //遍历结构体内部字段 t:=reflect.TypeOf(g) v:=reflect.ValueOf(g) for i:=0;i<t.NumField();i++{ //Field(i)获取第i个字段属性,Name则是获取名字。Type则是获取对应类型,如果比较的话,可以使用String()转成字符串类型 fmt.Println("字段名:",t.Field(i).Name," 值类型:", t.Field(i).Type.String()) /* 字段名: Name 值类型: string 字段名: Age 值类型: int 字段名: Gender 值类型: string 字段名: Length 值类型: int */ } for i:=0;i<v.NumField();i++{ fmt.Println("值类型:",v.Field(i).Type().String(), " 值类型:", v.Field(i).Kind().String(), " 值:", v.Field(i).Interface()) /* 值类型: string 值类型: string 值: satori 值类型: int 值类型: int 值: 16 值类型: string 值类型: string 值: f 值类型: int 值类型: int 值: 155 */ } }
反射操作函数
package main import ( "fmt" "reflect" "runtime" ) func foo(){} func main(){ t:=reflect.TypeOf(foo) v:=reflect.ValueOf(foo) fmt.Println(t.Name()) // 啥也没有 fmt.Println(t.Kind(), t.Kind().String() == "func") // func true fmt.Println(t.String(), t.String() == "func()") //func() true fmt.Println(v.Type())//func() fmt.Println(v.Kind())// func //我们在结构体中,t.Name()打印了是girl,t.String()打印的main.girl //v.Type()打印的是main.girl。这里Kind()打印的是类型本身是一个func和结构体类似,但是v.Type和t.Name()和t.String()应该打印函数名啊 //按照我们结构体的例子来说,t.Name()应该是foo,t.String()和v.Type()应该是main.foo才对啊,可这里不是,那我们如何获取函数名呢? fmt.Println(v.Interface()) //0x48e110, 这里打印的则是函数的内存地址,普通变量打印的是值 //目前是拿不到函数名了,但是有没有其他的办法呢?虽然有点复杂,但还是可以拿到的 pointer:=reflect.ValueOf(foo).Pointer() fmt.Println(runtime.FuncForPC(pointer).Name()) //main.foo fmt.Println(runtime.FuncForPC(pointer).Name() == "main.foo") //true }
golang中的反射的更多相关文章
- golang中的反射reflect详解
先重复一遍反射三定律: 1.反射可以将"接口类型变量"转换为"反射类型对象". 2.反射可以将"反射类型对象"转换为"接口类型变量 ...
- golang中的反射解析结构体标签tag
package main import ( "fmt" "reflect" ) type resume struct { // 反射解析结构体标签tag Nam ...
- Golang通脉之反射
什么是反射 官方关于反射定义: Reflection in computing is the ability of a program to examine its own structure, pa ...
- 七、golang中接口、反射
一.接口定义 1.定义 interface类型可以定义一组方法,但是这些不需要实现,并且interface不能包含任何变量 package main import ( "fmt" ...
- Golang中Struct与DB中表字段通过反射自动映射 - sqlmapper
Golang中操作数据库已经有现成的库"database/sql"可以用,但是"database/sql"只提供了最基础的操作接口: 对数据库中一张表的增删改查 ...
- Go 中的反射要点
简介 反射是元数据编程的一种形式,指的是程序获得本身结构的一种能力.不同语言的反射模型实现不一样,本文中的反射,仅仅指的是Go语言中的反射模型. 类型以及接口 这个基本概念需要清晰,这里不详细展开. ...
- Golang中的坑二
Golang中的坑二 for ...range 最近两周用Golang做项目,编写web服务,两周时间写了大概五千行代码(业务代码加单元测试用例代码).用Go的感觉很爽,编码效率高,运行效率也不错,用 ...
- 【荐】详解 golang 中的 interface 和 nil
golang 的 nil 在概念上和其它语言的 null.None.nil.NULL一样,都指代零值或空值.nil 是预先说明的标识符,也即通常意义上的关键字.在 golang 中,nil 只能赋值给 ...
- 六、golang中的结构体和方法、接口
结构体: 1.用来自定义复杂数据结构 2.struct里面可以包含多个字段(属性) 3.struct类型可以定义方法,注意和函数的区分 4.strucr类型是值类型 5.struct类型可以嵌套 6. ...
随机推荐
- 基于Vue、web3的以太坊项目开发及交易内幕初探 错误解决总结
基于Vue.web3的以太坊项目开发及交易内幕初探 本文通过宏观和微观两个层面窥探以太坊底层执行逻辑. 宏观层面描述创建并运行一个小型带钱包的发币APP的过程,微观层面是顺藤摸瓜从http api深入 ...
- Python参考
python中os模块用法 自动化运维Python系列(五)之常用模块 最常用的Notepad++的快捷键 pycharm快捷键 最全Pycharm教程(1)——定制外观 pycharm教程大全 py ...
- DFS(2)——hdu1241Oil Deposits
一.题目回顾 题目链接:Oil Deposits 题意:给你一块网格,网格被分为面积相等的地块,这些地块中标记'@'的是油田,标记'*'的不是油田.已知一块油田与它上下左右以及对角线的油田同属一片油区 ...
- lintcode-94-二叉树中的最大路径和
94-二叉树中的最大路径和 给出一棵二叉树,寻找一条路径使其路径和最大,路径可以在任一节点中开始和结束(路径和为两个节点之间所在路径上的节点权值之和) 样例 给出一棵二叉树: 返回 6 标签 动态规划 ...
- JMS实战——ActiveMQ实现Pub-Sub
前言 上篇博客<JMS实战--ActiveMQ>介绍了ActiveMQ的安装,并实现了简单的PTP模型.这篇博客我们来看一下Pub-Sub模型,之后来总结一下JMS. 实现 项目结构 其中 ...
- gdb查看内存中所有的信息
他们会把做内核的人当成无所不能的,认为你们对反编译啥的都应该会. 俗话说的好,人要活成别人想要的样子嘛: 看下如何停止进程,让大家看到内存中到底是啥样子; 简单的print globalA当然能输出来 ...
- [LeetCode] 70. Climbing Stairs(斐波那契数列)
[思路] a.因为两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1); b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2) c.由a.b ...
- 大并发量订单处理的 KafKa部署
大并发量订单处理的 KafKa部署总结 今天要介绍的是消息中间件KafKa,应该说是一个很牛的中间件吧,背靠Apache 与很多有名的中间件搭配起来用效果更好哦 ,为什么不用RabbitMQ,因为公司 ...
- AtCoder 神题汇总
记录平时打 AtCoder 比赛时遇到的一些神题. Tenka1 Programmer Contest 2019 D Three Colors 题目大意 有 $n$ 个正整数 $a_1, a_2,\d ...
- C&C++——extern
1.C 调用C++的函数或变量 C 调用C++的函数或变量,在C++的头文件声明为extern "C" ,C调用的时候只使用extern 声明. 可见,extern "C ...