golang中的标准库反射
反射
反射是指程序在运行期对程序本身访问和修改的能力
变量的内在机制
变量包含类型信息和值信息 var arr [10]int arr[0] = 10
类型信息:是静态的元信息,是预先定义好的
值信息:是程序运行过程中动态改变的
反射的使用
reflect包封装了反射相关的方法
获取类型信息:reflect.TypeOf,是静态的
获取值信息:reflect.ValueOf,是动态的
空接口和反射
反射可以在运行时动态获取程序的各种详细信息
反射获取interface类型信息
- 反射获取interface类型信息
func main() {
var x = math.Pi
reflectType(x)
}
func reflectType(tmp interface{}) {
t := reflect.TypeOf(tmp)
fmt.Println("类型是:", t)
// Kind()可以获取具体类型
k := t.Kind()
fmt.Println(k)
switch k {
case reflect.Float64:
fmt.Println("Float64类型")
case reflect.String:
fmt.Println("String类型")
}
}
- 反射获取interface的值信息
func main() {
var x = math.Pi
reflectValue(x)
}
func reflectValue(tmp interface{}) {
fmt.Printf("%v: %T\n", tmp, tmp)
v := reflect.ValueOf(tmp)
fmt.Println(v)
// 获取到v的具体类型
k := v.Kind()
fmt.Println(k)
switch k {
case reflect.Float64:
fmt.Println("float64类型")
}
}
- 反射修改值信息
func main() {
var x = math.Pi
// 反射修改值需要传递指针类型,不是float类型
reflectSetValue(&x)
fmt.Println("main: ", x)
}
func reflectSetValue(tmp interface{}) {
v := reflect.ValueOf(tmp)
k := v.Kind() // Kind() 获取具体类型
switch k {
case reflect.Float64:
// 反射修改值
v.SetFloat(15)
fmt.Println("tmp is", v.Float())
case reflect.Ptr:
// Elem获取地址指向的值
v.Elem().SetFloat(18)
fmt.Println("tmp is", v.Elem().Float())
fmt.Println(v.Pointer())
}
}
结构体与反射
- 查看类型、字段和方法
点击查看代码
type User struct {
Id int
Name string
Age int
}
func (u User) Hello() {
fmt.Println("Hello")
}
func main() {
u := User{11, "zhang", 18}
Poni(u)
}
func Poni(o interface{}) {
t := reflect.TypeOf(o)
fmt.Println("类型是:", t) // 类型是: main.User
fmt.Println(t.Name()) // User
v := reflect.ValueOf(o)
fmt.Println("值是:", v) // 值是: {11 zhang 18}
// 获取所有属性
// t.NumField 可以获取字段数量
for i := 0; i < t.NumField(); i++ {
// 获取每个字段
f := t.Field(i)
fmt.Println(f.Name, f.Type)
// 获取字段的值信息
val := v.Field(i).Interface() // Interface()获取字段对应的值
fmt.Println(val)
}
fmt.Println("==========方法===========")
for i := 0; i < t.NumMethod(); i++ {
m := t.Method(i)
fmt.Println(m.Name, m.Type)
}
}
- 查看匿名字段
点击查看代码
type User struct {
Id int
Name string
Age int
}
type Boy struct {
User
Addr string
}
func main() {
b := Boy{User{11, "zhang", 18}, "北京市"}
t := reflect.TypeOf(b)
fmt.Println(t) // main.Boy
// 匿名:Anonymous
fmt.Printf("%#v\n", t.Field(0))
// 输出:reflect.StructField{Name:"User", PkgPath:"", Type:(*reflect.rtype)(0x3de280), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:true}
// 值信息
fmt.Printf("%#v\n", reflect.ValueOf(b).Field(0))
}
- 修改结构体的值
点击查看代码
type User struct {
Id int
Name string
Age int
}
func main() {
u := User{11, "zhang", 18}
setValue(&u)
fmt.Println("main:", u)
}
// 修改结构体指向的值
func setValue(o interface{}) {
v := reflect.ValueOf(o)
// 获取指针指向的元素
v = v.Elem()
// 获取字段
f := v.FieldByName("Name")
if f.Kind() == reflect.String {
f.SetString("哈哈哈")
}
}
- 调用方法
点击查看代码
type User struct {
Id int
Name string
Age int
}
func (User) Hello(name string) {
fmt.Println("hello: ", name)
}
func main() {
u := User{11, "lisi", 88}
v := reflect.ValueOf(u)
// 获取方法
m := v.MethodByName("Hello")
// 构建一些参数
args := []reflect.Value{reflect.ValueOf("6666")}
// 没参数的情况下:var args2 []reflect.Value
// 调用方法,需要传入方法的参数
m.Call(args)
}
- 获取字段的tag
type Student struct {
Name string `json:"name1" db:"name2"`
}
func main() {
s := Student{Name: "lisi"}
v := reflect.ValueOf(&s)
// 注意:如果使用结构体指针,t.Elem()需要获取指针对应的值,如果使用的是s结构体,那么不需要t.Elem(),直接t.Field即可
// 类型
t := v.Type()
// 获取字段
f := t.Elem().Field(0)
fmt.Println(f.Tag.Get("json"))
fmt.Println(f.Tag.Get("db"))
}
golang中的标准库反射的更多相关文章
- golang中的标准库数据格式
数据格式介绍 是系统中数据交互不可缺少的内容 这里主要介绍JSON.XML.MSGPack JSON json是完全独立于语言的文本格式,是k-v的形式 name:zs 应用场景:前后端交互,系统间数 ...
- golang中的标准库context
在 Go http包的Server中,每一个请求在都有一个对应的 goroutine 去处理.请求处理函数通常会启动额外的 goroutine 用来访问后端服务,比如数据库和RPC服务.用来处理一个请 ...
- golang中的标准库log
Go语言内置的log包实现了简单的日志服务.本文介绍了标准库log的基本使用. 使用Logger log包定义了Logger类型,该类型提供了一些格式化输出的方法.本包也提供了一个预定义的" ...
- golang中的标准库context解读
简介 golang 中的创建一个新的 goroutine , 并不会返回像c语言类似的pid,所有我们不能从外部杀死某个goroutine,所有我就得让它自己结束,之前我们用 channel + se ...
- golang中的标准库http
Go语言内置的net/http包十分的优秀,提供了HTTP客户端和服务端的实现. http客户端 基本的HTTP/HTTPS请求 Get.Head.Post和PostForm函数发出HTTP/HTTP ...
- golang中的标准库template
html/template包实现了数据驱动的模板,用于生成可对抗代码注入的安全HTML输出.它提供了和text/template包相同的接口,Go语言中输出HTML的场景都应使用text/templa ...
- golang中的标准库IO操作
参考链接 输入输出的底层原理 终端其实是一个文件,相关实例如下: os.Stdin:标准输入的文件实例,类型为*File os.Stdout:标准输出的文件实例,类型为*File os.Stderr: ...
- golang中的标准库time
时间类型 time.Time类型表示时间.我们可以通过time.Now()函数获取当前的时间对象,然后获取时间对象的年月日时分秒等信息.示例代码如下: func main() { current := ...
- golang中的标准库strconv
strconv 包 strconv包实现了基本数据类型与其字符串表示的转换,主要有以下常用函数: Atoi().Itia().parse系列.format系列.append系列. string与int ...
随机推荐
- 【LeetCode】190. Reverse Bits 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 二进制字符串翻转 位运算 日期 题目地址:https://le ...
- 【剑指Offer】二叉树的深度 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 日期 题目地址:https://www.nowcoder.co ...
- Anniversary party(hdu1520)
Anniversary party Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- HAT
目录 概 主要内容 代码 Rade R. and Moosavi-Dezfooli S. Helper-based adversarial training: reducing excessive m ...
- Chapter 2 Randomized Experiments
目录 概 2.1 Randomization 2.2 Conditional randomization 2.3 Standardization 2.4 Inverse probability wei ...
- pandas tutorial 2
@ 目录 Group_By 对数据进行分组 对 group进行迭代 选择一个group get_group() Aggregations 在group的基础上传入函数整合 Transformation ...
- CS5218|DP转HDMI4K30HZ方案|CS5218应用方案
Capstone CS5218是一款单端口HDMI/DVI电平移位器/中继器,具有重新定时功能.它支持交流和直流耦合信号高达3.0-Gbps的操作与可编程均衡和抖动清洗.它包括2路双模DP电缆适配器寄 ...
- 关于使用JupyterNotebook运行代码运行到一半会闪退的问题
前几个星期使用Jupyter远程使用师兄的电脑跑了一段沐老师的代码学习,但是总是跑了一段就闪退,同时因为是远程桌面,远程桌面也被挤掉了. 具体表现就是:运行代码--表现正常,打印记录--远程桌面掉线- ...
- 懂得三境界-使用dubbo时请求超过问题
引子 刚才下班回家路上,无意中听到大街上放的歌,歌词有这么一句:"毡房外又有驼铃声声响起,我知道那一定不是你".这一句我似乎听懂了歌者的魂牵梦绕和绝望,如果在十年前我大概只能感受出 ...
- Java程序设计基础笔记 • 【第7章 Java中的类和对象】
全部章节 >>>> 本章目录 7.1 理解类和对象 7.1.1 对象 7.1.2 抽象与类 7.1.3 类与对象的关系: 7.2 Java中的类和对象 7.2.1 类的定义 ...