golang的反射探索

1、golang中反射常用的场景
1》类型检查—通用类包或者函数的时候,在运行时可以动态的获取任意对象的类型信息
2》动态调用方法—运行时动态的选择使用哪个方法
3》结构体标签处理—结构体字段一般是通过tag来注解。运行时可以通过反射读取tag。常用于解析配置文件,处理json,映射tag到某个特定的键。
4》动态操作结构体字段—运行时动态填充数据或者从一些通用的数据结构中提取数据。
5》实现通用编程-比如通用的库

2、三大定律
1》将接口类型变量转换为反射对象
反射对象指的是:reflect.type-表示接口值的类型信息和reflect.value-表示接口值的具体值,两种类型。

var x float64 = 1.1
v := x.reflect.ValueOf(x)//或者是typeOf()
// v是x的反射对象

v.type() // 表示类型
v.kind() // 表示底层的实际类型

2》反射对象可以转换为接口类型

var x float64 = 3.4v := reflect.ValueOf(x) // v是x的反射对象y := v.Interface().(float64) // 结果是3.4

3》要修改反射对象的值,其值必须是可以被设置的。(地址是不能直接去修改对应值的)

vv := reflect.ValueOf(&x)
vv.Elem().Set(reflect.ValueOf(111.11))
fmt.Println(x)

3、反射的常用场景示例
结构体为例
1》获取变量和方法

var ss = Student {Username:"aa",Age:11,
}
typeS := reflect.TypeOf(ss)
numField := typeS.NumField()
for i:=0;i<numField;i++ {field := typeS.Field(i)fmt.Printf("变量名:%s, 变量是否可见:%s, 变量的tag是:%s\n",field.Name, field.Anonymous, field.Tag)}

/*
输出结果是:
变量名:Username, 变量是否可见:%!s(bool=false), 变量的tag是:json:userName
变量名:Age, 变量是否可见:%!s(bool=false), 变量的tag是:json:age
*/


```go
func (s Student) GetName() string {return s.GetName()
}
// 注意这里是指针
func (s *Student) GetAge() int {return s.GetAge()
}// 这里获取的时候也是指针
typeStudentPoint := reflect.TypeOf(&ss)methodPoint := typeStudentPoint.NumMethod()for i:=0;i<methodPoint;i++ {method := typeStudentPoint.Method(i)fmt.Printf("method name:%s, type:%s\n", method.Name, method.Type)}/**
输出结果是:
method name:GetAge, type:func(*main.Student) int
method name:GetName, type:func(*main.Student) string
*/如果上面在获取typeof的时候,传进去的不是指针。那么结果又是怎么样呢?
结果是这样的:
method name:GetName, type:func(main.Student) string所以最好传进去地址,才能最大程度的使用所有的方法。

2、获取函数信息

func (s *Student) Add(a, b int) int {return a+b
}var ss = &Student {Username:"aa",Age:11,
}
var ss = &Student {Username:"aa",Age:11,}typeadd := reflect.TypeOf(ss.Add)for i:=0;i<typeadd.NumIn();i++ {fmt.Printf("%s\n",typeadd.In(i).Kind())}for i:=0;i<typeadd.NumOut();i++ {fmt.Printf("%s\n",typeadd.Out( i).Kind())}

3、是否实现了接口

type People interface {Color() string
}type Child struct {
}func (c *Child) Color() string {return "this is a child"
}type Dog struct {
}peopleType := reflect.TypeOf((*People)(nil)).Elem()fmt.Println("people is interface?", peopleType.Kind() == reflect.Interface)noPointChildType := reflect.TypeOf(Child{})pointChildType := reflect.TypeOf(&Child{})noPointDogType := reflect.TypeOf(Dog{})pointDogType := reflect.TypeOf(&Dog{})fmt.Println("nopoint child 是否实现了people接口:\n", noPointChildType.Implements(peopleType))fmt.Println("point child 是否实现了people接口:\n", pointChildType.Implements(peopleType))fmt.Println("nopoint dog 是否实现了people接口:\n", noPointDogType.Implements(peopleType))fmt.Println("nopoint dog 是否实现了people接口:\n", pointDogType.Implements(peopleType))/**
输出结果如下:
people is interface? true
nopoint child 是否实现了people接口:false
point child 是否实现了people接口:true
nopoint dog 是否实现了people接口:false
nopoint dog 是否实现了people接口:false*/

4、value转type

s := Student{Username:"miss zhao",}sValueOf := reflect.ValueOf(&s)fmt.Println(sValueOf.Elem().FieldByName("Username"))sTypeOf := sValueOf.Type()fmt.Println(sTypeOf)/**
输出结果如下:
miss zhao
*main.Student
*/

5、指针和非指针互转

// 指针和非指针互转s := Student{Username:"miss zhao",}// 指针sValueOf := reflect.ValueOf(&s)// 非指针noPoint := sValueOf.Elem()//*main.Student main.Studentfmt.Println(sValueOf.Type(), noPoint.Type())//互转point := noPoint.Addr()//*main.Studentfmt.Println(point.Type())

6、获取原始类型

s := Student{Username:"miss zhao",}sValueOf := reflect.ValueOf(&s)noPoint := sValueOf.Elem()// 转换为原始类型s = noPoint.Interface().(Student)fmt.Println(s.Username)

7、空value值的判断

// 相当于anyvar i interface{}v := reflect.ValueOf(i)fmt.Println(v.Kind() == reflect.Invalid)// 判断是否nilvar ss *Student = nilv = reflect.ValueOf(ss)if v.IsValid(){fmt.Println(v.IsNil())}//只声明 所有的值都是零值var s Studentv = reflect.ValueOf(s)// 必须先判断isValidif v.IsValid() {fmt.Println(v.IsZero())}

8、调用方法

func (s *Student) Add(a, b int) int {return a+b
}// main函数里
s := Student{Username:"miss zhao",}// 注意:使用指针可以调用指针和非指针的方法ss := reflect.ValueOf(&s)methodByName := ss.MethodByName("Add")resultSlice := methodByName.Call([]reflect.Value{reflect.ValueOf(1), reflect.ValueOf(2)})fmt.Println(resultSlice[0].Interface().(int))
/**
这里的输出结果如下:
3
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/707579.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

雾锁王国Enshrouded服务器CPU内存配置怎么选择?

雾锁王国/Enshrouded服务器CPU内存配置如何选择&#xff1f;阿里云服务器网aliyunfuwuqi.com建议选择8核32G配置&#xff0c;支持4人玩家畅玩&#xff0c;自带10M公网带宽&#xff0c;1个月90元&#xff0c;3个月271元&#xff0c;幻兽帕鲁服务器申请页面 https://t.aliyun.com…

使用 Go 语言读取文件内容并进行反序列化

在现代软件开发过程中&#xff0c;经常需要读取配置文件或数据文件&#xff0c;并将这些文件的内容转换成程序可以理解和操作的数据结构。对于使用Go语言的开发者来说&#xff0c;标准库中提供的一系列工具和包能够帮助完成从文件读取到数据反序列化的整个流程&#xff0c;特别…

通过shell编写内存监视的脚本来介绍一些基本shell脚本操作

目录 知识概览 总体脚本编写 date awk grep bc 知识概览 总体脚本编写 #!/bin/bash#定义日志的文件名和日期 cdate$(date %Y%m%d%H%M%S) logfile"/tmp/memlog_{$0}.log"#拿到ip ip_addr$(ip add|grep "ens33$"|awk {print $2})#总内存和使用的内存 m…

成为大佬之路--linux软件安装使用第000000018篇--linux安装nacos

官网 Nacos官网 | Nacos 官方社区 | Nacos 下载 | Nacos 安装包 Releases alibaba/nacos GitHub 安装 1.创建目录 mkdir -p /opt/nacos cd /opt/nacos 2.下载安装包 wget https://github.com/alibaba/nacos/releases/download/1.4.7/nacos-server-1.4.7.tar.gz 3.解压…

如何使用Fastapi上传文件?先从请求体数据讲起

文章目录 1、请求体数据2、form表单数据3、小文件上传1.单文件上传2.多文件上传 4、大文件上传1.单文件上传2.多文件上传 1、请求体数据 前面我们讲到&#xff0c;get请求中&#xff0c;我们将请求数据放在url中&#xff0c;其实是非常不安全的&#xff0c;我们更愿意将请求数…

springboot/ssm高校疫情防控系统Java校园疫情防控管理平台web

springboot/ssm高校疫情防控系统Java校园疫情防控管理平台web 基于springboot(可改ssm)vue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;…

第三百七十二回

文章目录 1. 概念介绍2. 实现方法2.1 maskFilter2.2 shader 3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"两种阴影效果"相关的内容&#xff0c;本章回中将介绍如何绘制阴影效果.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概…

LeetCode刷题笔记之二叉树(三)

一、寻找特定节点 1. 404【左叶子之和】 题目&#xff1a; 给定二叉树的根节点 root &#xff0c;返回所有左叶子之和。代码&#xff1a; class Solution {public int sumOfLeftLeaves(TreeNode root) {//左叶子不止是最左边的叶子&#xff0c;而是二叉树中每个节点的左叶子…

java多线程并发实战,java高并发场景面试题

阶段一&#xff1a;筑基 Java基础掌握不牢&#xff0c;对于一个开发人员来说无疑是非常致命的。学习任何一个技术知识无疑不是从基础开始&#xff1b;在面试的时候&#xff0c;面试官无疑不是从基础开始拷问。 内容包括&#xff1a;Java概述、Java基本语法、Java 执行控制流程、…

html5盒子模型

1.边框的常用属性 border-color 属性 说明 示例 border-top-color 上边框颜色 border-top-color:#369; border-right-color 右边框颜色 border-right-color:#369; border-bottom-color 下边框颜色 border-bottom-color:#fae45b; border-left-color 左边框颜色…

java springmvc/springboot 项目通过HttpServletRequest对象获取请求体body工具类

请求 测试接口 获取到的 获取到打印出的json字符串里有空格这些&#xff0c;在json解析的时候正常解析为json对象了。 工具类代码 import lombok.extern.slf4j.Slf4j; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.we…

【前端开发】前端开发深度解析:HTML、CSS、JavaScript与Vue.js

一、HTML&#xff1a;构建网页的基石 1.1 简介 HTML&#xff08;HyperText Markup Language&#xff0c;超文本标记语言&#xff09;是一种用于创建网页的标准标记语言。它使用各种标签&#xff08;tags&#xff09;来描述网页上的内容&#xff0c;包括文本、图像、链接、视频…

类的继承extends以及super

类的继承 继承&#xff1a;基于父类的某个扩展&#xff0c;制定出一个新的子类&#xff0c;而这个子类可以继承父类的原有属性和方法 java是如何体现继承的特性的 平板电脑继承了台式机电脑所拥有的功能(如听音乐)的基础上&#xff0c;同时扩展出自己特殊的用途&#xff1a;如…

pikachu之xss获取键盘记录

前备知识 跨域 跨域&#xff08;Cross-Origin&#xff09;是指在互联网中&#xff0c;浏览器为了保护用户信息安全而实施的一种安全策略——同源策略&#xff08;Same-Origin Policy&#xff09;&#xff0c;即浏览器禁止一个域上的文档或者脚本&#xff08;如通过JavaScript发…

从零开始学习Netty - 学习笔记 -Netty入门-ChannelFuture

5.2.2.Channel Channel 的基本概念 在 Netty 中&#xff0c;Channel 是表示网络传输的开放连接的抽象。它提供了对不同种类网络传输的统一视图&#xff0c;比如 TCP 和 UDP。 Channel 的生命周期 Channel 的生命周期包括创建、激活、连接、读取、写入和关闭等阶段。Netty 中…

QT C++实战:实现用户登录页面及多个界面跳转

主要思路 一个登录界面&#xff0c;以管理员Or普通用户登录管理员&#xff1a;一个管理员的操作界面&#xff0c;可以把数据录入到数据库中。有返回登陆按钮&#xff0c;可以选择重新登陆&#xff08;管理员Or普通用户普通用户&#xff1a;一个主界面&#xff0c;负责展示视频…

【0267】pg内核初始化 process table(ProcGlobal、PROC_HDR、PGPROC)分析

1. 前言 在postmaster或standalone后端启动期间初始化全局进程表(global process table)。该过程由InitProcGlobal()完成,对于此函数: (1)还创建了支持所请求的后端数量所需的所有每个进程信号量。我们过去只在后端真正启动时才分配信号量,但这很糟糕,因为它会让Postg…

vue组件中data为什么必须是一个函数

查看本专栏目录 关于作者 还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#x…

JVM-垃圾回收

一、概念 垃圾回收是JVM的堆中管理内存的一种办法。JVM会在特定条件下回收无用的对象占用的内存空间。 二、判断垃圾的方法 1、引用计数法 这种判断某一对象是否是垃圾的方法的原理是&#xff1a;记录某个对象被引用的次数&#xff0c;如果引用次数是0说明是垃圾。但是有漏…

GameObject类API学习

GameObject类 GameObject类是Unity场景中所有实体的基类。一个GameObject对象通常由多个组件组成&#xff0c;且至少含有一个Transform组件。 1、GameObject类实例属性 在GameObject类中&#xff0c;实例属性有activeSelf和activeInHierarchy。 activeSelf属性&#xff1a;…