Golang 进阶5—— 反射
Golang 进阶5—— 反射
注意,该文档只适合有编程基础的同学,这里的go教程只给出有区别的知识点
反射:
- 反射可以在运行时动态获取变量的各种信息, 比如变量的类型、 类别等信息。
- 如果是结构体变量,还可以获取结构体本身的信息(结构体的字段、方法)。
- 通过反射, 可以修改变量的值,可以调用关联的方法。
- 使用反射, 需要import(“reflect”)
1.1 main函数
package mainimport ("fmt""reflect"
)// 利用一个函数, 函数的参数定义为空接口
// 空接口没有任何方法,所以可以理解为所有类型都实现了空接口
// 也可以理解为我们可以把任何一种类型赋值给空接口
func testReflect (data interface{}) {// 1、 调用 TypeOf函数, 返回reflect.Type 类型的数据fmt.Println("data type is ", reflect.TypeOf(data))// 2、 调用 ValueOf函数, 返回reflect.Value 类型的数据reVal := reflect.ValueOf(data)fmt.Println("data value is ", reVal)// 3、 如果要获取具体类型的值, 可以调用 Int 方法sum := 100 + reVal.Int()fmt.Println("sum is ", sum)// 4、 reVal 转成空接口i2 := reVal.Interface()fmt.Println("i2 is ", i2)// 5、类型断言n := i2.(int)n2 := n + 200fmt.Println("n2 is ", n2)fmt.Println("i2 type is ", reflect.TypeOf(i2))
}
1.2 输出结果
(base) PS E:\Goproject\src\gocode\testproject03> go run .\main\main.go
data type is int
data value is 10
sum is 110
i2 is 10
n2 is 210
i2 type is int
1.3 结构体情况
import ("fmt""reflect"
)type Student struct {Name stringAge int
}// 利用一个函数, 函数的参数定义为空接口
// 空接口没有任何方法,所以可以理解为所有类型都实现了空接口
// 也可以理解为我们可以把任何一种类型赋值给空接口
func testReflect (data interface{}) {// 1、 调用 TypeOf函数, 返回reflect.Type 类型的数据fmt.Println("data type is ", reflect.TypeOf(data))// 2、 调用 ValueOf函数, 返回reflect.Value 类型的数据reVal := reflect.ValueOf(data)fmt.Println("data value is ", reVal)// 3、 reVal 转成空接口i2 := reVal.Interface()fmt.Println("i2 is ", i2)if s, ok := i2.(Student); ok {fmt.Println("i2 is student:", s.Name)} else {fmt.Println("i2 is not a student")}
}func main () {stu1 := Student{"xiaoxiao", 18}testReflect(stu1)
}
1.4 输出结果
(base) PS E:\Goproject\src\gocode\testproject03> go run .\main\main.go
data type is main.Student
data value is {xiaoxiao 18}
i2 is {xiaoxiao 18}
i2 is student: xiaoxiao
1.5 获取变量类别
import ("fmt""reflect"
)type Student struct {Name stringAge int
}// 利用一个函数, 函数的参数定义为空接口
// 空接口没有任何方法,所以可以理解为所有类型都实现了空接口
// 也可以理解为我们可以把任何一种类型赋值给空接口
func testReflect (data interface{}) {// 1、 调用 TypeOf函数, 返回reflect.Type 类型的数据reType := reflect.TypeOf(data)fmt.Println("data type is ", reType)// 2、 调用 ValueOf函数, 返回reflect.Value 类型的数据reVal := reflect.ValueOf(data)fmt.Println("data value is ", reVal)// 3、 获取变量的类别(大范围)k1 := reVal.Kind()fmt.Println("data kind is ", k1)k2 := reType.Kind()fmt.Println("data kind is ", k2)// 4、 获取变量的类型 (小范围)i2 := reVal.Interface()if n, ok := i2.(Student); ok {fmt.Println("n is ", n)} else {fmt.Println("n is not Student")}}func main () {stu1 := Student{"xiaoxiao", 18}testReflect(stu1)
}
1.6 输出结果
(base) PS E:\Goproject\src\gocode\testproject03> go run .\main\main.go
data type is main.Student
data value is {xiaoxiao 18}
data kind is struct
data kind is struct
n is {xiaoxiao 18}
1.7 对结构体操作
// 1. 定义结构体
type Student struct {Name stringAge int
}// 2. 给结构体绑定方法
func (stu Student) Print() {fmt.Print("调用了Print方法")fmt.Println(stu)
}func (stu Student) GetSum(n1, n2 int) int {return n1 + n2
}func (stu Student) Set(name string, age int) {stu.Name = namestu.Age = age
}func testReflect(data interface{}) {reVal := reflect.ValueOf(data)// 检查 data 是否是指针,并获取指向的值if reVal.Kind() == reflect.Ptr {reVal = reVal.Elem()}fmt.Println(reVal)// 获取结构体中字段的数量n1 := reVal.NumField()fmt.Println("字段的数量:", n1)for i := 0; i < n1; i++ {// 输出字段fmt.Printf("字段 %d 的名字是 %s, 对应的值为 %v \n", i, reVal.Type().Field(i).Name, reVal.Field(i))}// 获取结构体的方法数量n2 := reVal.NumMethod()fmt.Println("方法的数量:", n2)// 输出方法for i := 0; i < n2; i++ {// 输出方法fmt.Printf("方法 %d 的名字是 %s \n", i, reVal.Type().Method(i).Name)}// 调用方法, 调用的方法首字母必须大写reVal.MethodByName("Print").Call(nil)// 调用GetSum方法// 定义Value切片var params []reflect.Valueparams = append(params, reflect.ValueOf(10))params = append(params, reflect.ValueOf(20))sum := reVal.MethodByName("GetSum").Call(params)fmt.Println("sum = ", sum[0])
}func main() {stu := Student{Name: "Tom", Age: 18}testReflect(stu) // 传入 stu 的指针
}
1.8 输出结果
(base) PS E:\Goproject\src\gocode\testproject03> go run .\main\main.go
{Tom 18}
字段的数量: 2
字段 0 的名字是 Name, 对应的值为 Tom
字段 1 的名字是 Age, 对应的值为 18
方法的数量: 3
方法 0 的名字是 GetSum
方法 1 的名字是 Print
方法 2 的名字是 Set
调用了Print方法{Tom 18}
sum = 30
1.9 改值
import ("fmt""reflect"
)// 1. 定义结构体
type Student struct {Name stringAge int
}// 2. 给结构体绑定方法
func (stu Student) Print() {fmt.Print("调用了Print方法")fmt.Println(stu)
}func (stu Student) GetSum(n1, n2 int) int {return n1 + n2
}func (stu Student) Set(name string, age int) {stu.Name = namestu.Age = age
}func testReflect(data interface{}) {reVal := reflect.ValueOf(data)// 通过setInt方法修改值n := reVal.Elem().NumField()fmt.Println("结构体中字段个数为:", n)reVal.Elem().Field(0).SetString("Jack")reVal.Elem().Field(1).SetInt(30)
}func main() {stu := Student{Name: "Tom", Age: 18}testReflect(&stu) // 传入 stu 的指针fmt.Println(stu)
}
1.10 输出结果
(base) PS E:\Goproject\src\gocode\testproject03> go run .\main\main.go
结构体中字段个数为: 2
{Jack 30}
相关文章:
Golang 进阶5—— 反射
Golang 进阶5—— 反射 注意,该文档只适合有编程基础的同学,这里的go教程只给出有区别的知识点 反射: 反射可以在运行时动态获取变量的各种信息, 比如变量的类型、 类别等信息。如果是结构体变量,还可以获取结构体本…...
react 封装防抖
封装防抖 import React, { useRef, useEffect, useCallback } from react;function useDebounce(fn, delay) {const delayRef useRef(delay);const fnRef useRef(fn);// 更新ref值useEffect(() > {delayRef.current delay;}, [delay]);useEffect(() > {fnRef.current…...
Java项目-----图形验证码登陆实现
原理: 验证码在前端显示,但是是在后端生成, 将生成的验证码存入redis,待登录时,前端提交验证码,与后端生成的验证码比较. 详细解释: 图形验证码的原理(如下图代码).前端发起获取验证码的请求后, 1 后端接收请求,生成一个键key(随机的键) 然后生成一个验证码作为map的valu…...
【网络代理模块】反向代理(上)
1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求,然后将请求转发给内部网络上的服务器,将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说,反向代理就相当…...
2-112基于matlab的协同干扰功率分配模型
基于matlab的协同干扰功率分配模型,带操作界面的功率分配GUI,可以实现对已有功率的分配优化,可以手动输入参数值。4个干扰山区分二批总干扰功率,每个扇区包括威胁总系数、综合压制概率、目标函数增量等。程序已调通,可…...
数据结构之——二叉树
一、二叉树的基本概念 二叉树是数据结构中的重要概念,每个节点最多有两个子树,分别为左子树和右子树。这种结构具有明确的层次性和特定的性质。 二叉树有五种基本形态: 空二叉树:没有任何节点。只有一个根结点的二叉树ÿ…...
多层感知机(MLP)实现考勤预测二分类任务(sklearn)
1、基础应用: https://blog.csdn.net/qq_36158230/article/details/118670801 多层感知机(MLP)实现考勤预测二分类任务(sklearn) 2、分类器参数:https://scikit-learn.org/dev/modules/generated/sklearn.neural_network.MLPClassifier.html 3、损失函数…...
文件与目录的基本操作
前提:使用su root 切换到权限最大的root用户 1.显示当前工作目录的绝对路径(pwd) 用途:用于显示当前工作目录的绝对路径的命令。无论用户在文件系统的哪个位置,pwd 命令都能提供当前所在位置的完整路径信息。 用法&a…...
Python入门笔记(三)
文章目录 第八章 字典dict8.1 创建字典:{}、dict()、字典生成式、zip()8.2 获取键对应的值:get()8.3 in, not in判断键是否在字典中8.4 增加键值对:fromkeys()、setdefault()、update()8.5 删除键值对:del语句、clear(…...
PostgreSQL 任意命令执行漏洞(CVE-2019-9193)
记一次授权攻击通过PostgreSql弱口令拿到服务器权限的事件。 使用靶机复现攻击过程。 过程 在信息收集过程中,获取到在公网服务器上开启了5432端口,尝试进行暴破,获取到数据库名为默认postgres,密码为1 随后连接进PostgreSql …...
使用tgz包下载安装clickhouse低版本
1.下载安装包 官方下载地址:https://packages.clickhouse.com/tgz/stable 阿里云下载地址:clickhouse-tgz-stable安装包下载_开源镜像站-阿里云 共需要下载四个文件 clickhouse-common-static-20.3.10.75.tgz clickhouse-common-static-dbg-20.3.10.7…...
外包功能测试干了6个月,技术退步太明显了。。。。。
先说一下自己的情况,本科生,23年通过校招进入武汉某软件公司,干了差不多6个月的功能测试,今年中秋,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我就在一个外包企业干了6个月的功…...
动态规划和贪心算法
目录 动态规划和贪心算法 动态规划 贪心算法 两者之间的区别 动态规划和贪心算法 是两种经典的算法设计策略,它们各自具有独特的特点和适用场景。 动态规划 动态规划是一种将复杂问题分解为更简单子问题的求解方法。它特别适用于那些具有重叠子问题和最优子结构特性的问…...
python爬虫--tx动漫完整信息抓取
python爬虫--tx动漫完整信息抓取 一、采集主页信息二、采集详情页信息三、完整代码一、采集主页信息 先看一下采集到的信息,结果保存为csv文件: 打开开发者工具,找到数据接口。 使用xpath提取详情页url。 二、采集详情页信息 如上图所示,使用xpath提取详情页的标题、作…...
《使用Java做爬虫和使用python做爬虫哪个好》
使用Java做爬虫和使用python做爬虫哪个好 Java 和 Python 都是非常出色的编程语言,在爬虫领域各有其优势,具体使用哪种语言更好取决于多种因素: 一、开发效率 1. Python Python 以其简洁、易读的语法而闻名。在爬虫开发中,有许…...
如果我想开发一个APP,需要准备哪些材料呢
开发一个APP需要准备的材料相对复杂,涵盖了公司资质、技术资源、支付接口以及第三方服务等多个方面。以下是一份详细的材料清单: 一、公司资质证明 营业执照:需要提供公司的营业执照副本,用于申请企业支付、域名备案、APP上架及…...
告别论文初稿焦虑!ChatGPT让你轻松完成写作!
AIPaperGPT,论文写作神器~ https://www.aipapergpt.com/ 在面对繁琐的论文写作时,很多人都会遇到无从下手的困惑,尤其是论文初稿阶段,往往需要大量的时间来组织思路和编写内容。然而,随着AI技术的发展,像…...
mongodb 数据迁移,亲测成功!
mysql进行数据迁移,最简单的不过是导出sql,然后在运行sql,数据也自然迁移过去了。 可是mongodb里,我们存储的是文件,是怎么做到的呢,当我在翻阅网上博客的时候,并没有发现有这方面的顾虑。 当…...
如何使用ssm实现疫情居家办公OA系统
TOC 10902ssm疫情居家办公OA系统 系统概述 进过系统的分析后,就开始记性系统的设计,系统设计包含总体设计和详细设计。总体设计只是一个大体的设计,经过了总体设计,我们能够划分出系统的一些东西,例如文件、文档、数…...
深入了解 MySQL 中的 JSON_CONTAINS
深入了解 MySQL 中的 JSON_CONTAINS MySQL 5.7 及更高版本引入了对 JSON 数据类型的支持,使得在数据库中存储和查询 JSON 数据成为可能。在这些新功能中,JSON_CONTAINS 函数是一个非常有用的工具,允许我们检查一个 JSON 文档是否包含特定的值…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
