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 ...
随机推荐
- 制作一个文档同步工具,自动同步到gitee中。。。
之所以要做这个工具是为了让自己可以随时用电脑时能记录日常工作或生活.一般只需要简单记录下就行了.这样我在家里的和公司里的记录都能同步看到. 这样后期整理的时候看到几个关键词就能想起来具体的事情,有的也 ...
- IM服务器:编写一个健壮的服务器程序需要考虑哪些问题
如果是编写一个服务器demo,比较简单,只要会socket编程就能实现一个简单C/S程序,但如果是实现一个健壮可靠的服务器则需要考虑很多问题.下面我们看看需要考虑哪些问题. 一.维持心跳 为何要维持心 ...
- JAVA中数组(Array)、字符串(String)、集合(List、Set)相互转换
1.数组转List String[] arr = new String[]{"A", "B", "C"}; List list = Arra ...
- UiPath RPA培训2021.4版本解读 (2021年5月)-RPA学习天地
2021年5月26日Ui Path发布了新产品2021.4版本,我们来看看有什么新功能: 说明一下uipath的版本发布节奏: uipath的版本一般是每年发布2个版本,其中5月份发布的一般是FTS版 ...
- nanogui源码编译+下载
MAC 没电了,哎..... 只能使用windows10将就了. 截至目前,我已经找到了两个nanogui项目,都是大佬. 分别为: A.https://github.com/dalerank/ ...
- 【LeetCode】733. Flood Fill 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:DFS 方法二:BFS 日期 题目地址:ht ...
- 【LeetCode】423. Reconstruct Original Digits from English 解题报告(Python)
[LeetCode]423. Reconstruct Original Digits from English 解题报告(Python) 标签: LeetCode 题目地址:https://leetc ...
- idea使用教程-模板的使用
一.代码模板是什么 它的原理就是配置一些常用代码字母缩写,在输入简写时可以出现你预定义的固定模式的代码,使得开发效率大大提高,同时也可以增加个性化.最简单的例子就是在Java中输入sout会出现Sys ...
- Autofac 依赖注入小知识
Autofac 依赖注入小知识 控制反转/依赖注入 IOC/DI 依赖接口而不依赖于实现,是面向对象的六大设计原则(SOLID)之一.即依赖倒置原则(Dependence Inversion Prin ...
- Dynamic Routing Between Capsules
目录 概 主要内容 损失函数 代码 Sabour S, Frosst N, Hinton G E, et al. Dynamic Routing Between Capsules[C]. neural ...