当前位置: 首页 > news >正文

golang学习笔记27-反射【重要】

本节也是GO核心部分,很重要。包括基本类型的反射,结构体类型的反射,类别方法Kind(),修改变量的值。

目录

    • 一、概念,基本类型的反射
    • 二、结构体类型的反射
    • 三、类别方法Kind()
    • 四、修改变量的值

一、概念,基本类型的反射

【1】反射可以做什么?
1)反射可以在运行时动态获取变量的各种信息,比如变量的类型,类别等信息
2)如果是结构体变量,还可以获取到结构体本身的信息(包括结构体的字段、方法)
3)通过反射,可以修改变量的值,可以调用关联的方法。
4)使用反射,需要import "reflect"
【2】反射相关的函数
1)reflect.TypeOf(变量名),获取变量的类型,返回reflect.Type类型
2)reflect.ValueOf(变量名),获取变量的值,返回reflect.Value类型
反射不仅可以获取变量名和变量类型,reflect.Type也可以通过空接口转回原类型:

package mainimport ("fmt""reflect"
)func main() {// 定义一个变量var x int = 42// 获取变量的类型t := reflect.TypeOf(x)fmt.Println("Type:", t) // 输出: Type: int// 获取变量的值v := reflect.ValueOf(x)fmt.Println("Value:", v) // 输出: Value: 42// 将 reflect.Value 转换回原始类型// Step 1: 将 reflect.Value 转换为 empty interface (interface{})emptyInterface := v.Interface() // 这里使用空接口可以接受任何类型的值// Step 2: 使用类型断言将 empty interface 转换回原始类型 intoriginalValue := emptyInterface.(int)         // 将空接口断言为 int 类型fmt.Println("Original value:", originalValue) // 输出: Original value: 42
}

反射和数据类型互转的流程图如下:
在这里插入图片描述

二、结构体类型的反射

和基本类型的情况差不多,但要注意因为实现接口的结构体可能有多个,接口转结构体要判断是否转成功:

package mainimport ("fmt""reflect"
)// 定义 student 结构体
type student struct {Name stringAge  int
}func main() {// 创建一个 student 实例s := student{Name: "Alice", Age: 20}// 获取变量的类型t := reflect.TypeOf(s)fmt.Println("类型:", t) // 输出: 类型: main.student// 获取变量的值v := reflect.ValueOf(s)fmt.Println("值:", v) // 输出: 值: {Alice 20}// 将 reflect.Value 转换回原始类型// Step 1: 将 reflect.Value 转换为 empty interface (interface{})emptyInterface := v.Interface() // 这里使用空接口可以接受任何类型的值// Step 2: 使用类型断言将 empty interface 转换回原始类型 studentoriginalStudent, ok := emptyInterface.(student) // 将空接口断言为 student 类型if ok {// 如果转换成功,输出姓名和年龄fmt.Printf("原始学生 - 姓名: %s, 年龄: %d\n", originalStudent.Name, originalStudent.Age) // 输出: 原始学生 - 姓名: Alice, 年龄: 20} else {fmt.Println("类型断言为 student 失败。")}
}

三、类别方法Kind()

Kind()是reflect.Type的一个方法,用于获取类型的基本种类(kind)。它返回一个reflect.Kind类型的值,用于描述基本数据类型的特性,如int、string、struct等。
Kind()和TypeOf()的区别如下表所示:

特性reflect.TypeOf()reflect.Kind()
返回值返回 reflect.Type 类型的对象返回 reflect.Kind 类型的枚举值
作用获取变量的完整类型信息获取变量的基本种类(如 intstringstruct
适用场景当需要获取类型的详细信息时当只需要判断数据类型的基本特性时

语法:TypeOf(s).Kind()ValueOf(s).Kind(),这两个操作都返回变量s的基本类型。

四、修改变量的值

如果用反射修改x的类型,需要先获取reflect.Value类型,然后用对应x类型的方法,比如SetInt(),如果x是int*,则需要先用Elem(),再用SetInt():

package mainimport ("fmt""reflect"
)func main() {var x int = 42p := &x // 创建指向 x 的指针// 获取指针的 reflect.Valuev := reflect.ValueOf(p)// 使用 Elem() 获取指针指向的值elem := v.Elem()// 修改指针指向的值elem.SetInt(100)// 输出修改后的值fmt.Println("修改后的值:", x) // 输出: 修改后的值: 100
}

如果x是结构体,要用Field()获取字段,Method()获取方法,用reflect.Value切片调用有参方法,用nil调用无参方法:

package mainimport ("fmt""reflect"
)// 定义 student 结构体
type student struct {Name stringAge  int
}// 为 student 结构体定义一个方法
func (s *student) SetAge(age int) {s.Age = age
}// 为 student 结构体定义另一个方法
func (s *student) GetInfo() string {return fmt.Sprintf("姓名: %s, 年龄: %d", s.Name, s.Age)
}func main() {// 创建一个 student 实例s := student{Name: "Alice", Age: 20}// 获取结构体的类型,使用指针获取stuType := reflect.TypeOf(&s)// 获取字段数量numFields := stuType.Elem().NumField() // 使用 Elem() 获取底层类型fmt.Printf("字段数量: %d\n", numFields)// 遍历字段for i := 0; i < numFields; i++ {field := stuType.Elem().Field(i) // 使用 Elem() 获取底层类型的字段fmt.Printf("字段名: %s, 字段类型: %s\n", field.Name, field.Type)}// 获取方法数量numMethods := stuType.NumMethod() // 获取方法数量fmt.Printf("方法数量: %d\n", numMethods)// 遍历方法for i := 0; i < numMethods; i++ {method := stuType.Method(i)fmt.Printf("方法名: %s\n", method.Name)}// 使用反射修改 Name 字段的值stuValue := reflect.ValueOf(&s)       // 获取结构体的反射值,使用指针可以修改值nameField := stuValue.Elem().Field(0) // 获取第一个字段的反射值// 确保字段可设置if nameField.CanSet() {nameField.SetString("Bob") // 修改 Name 字段的值为 "Bob"}// 调用 SetAge 方法,将年龄设置为 30setAgeMethod := stuValue.MethodByName("SetAge")args := []reflect.Value{reflect.ValueOf(30)} // 创建包含参数的切片setAgeMethod.Call(args)                      // 调用 SetAge 方法,传入参数// 调用 GetInfo 方法getInfoMethod := stuValue.MethodByName("GetInfo")info := getInfoMethod.Call(nil) // 调用方法,传递空参数// 输出信息fmt.Println(info[0]) // 输出: 姓名: Bob, 年龄: 30
}

关键代码解释:
1.info := getInfoMethod.Call(nil)
infoMethod是通过反射获取到的一个方法的反射值。在这个例子中,它指向student结构体的Info方法。Call是reflect.Value类型的方法,用于调用一个方法。它接受一个参数,参数是一个reflect.Value切片,表示要传递给被调用方法的参数。在这里,我们传递了nil,表示Info方法不需要任何参数。在这个例子中,GetInfo方法返回一个字符串,因此info将是一个包含一个reflect.Value的切片,表示学生信息字符串。
2. args := []reflect.Value{reflect.ValueOf(30)}
这一行创建了一个reflect.Value切片,命名为args,它将用于调用SetAge方法。reflect.ValueOf(30)用于将整数30转换为reflect.Value类型。[]reflect.Value{}表示创建一个reflect.Value类型的切片,作为SetAge方法的参数。

相关文章:

golang学习笔记27-反射【重要】

本节也是GO核心部分&#xff0c;很重要。包括基本类型的反射&#xff0c;结构体类型的反射&#xff0c;类别方法Kind()&#xff0c;修改变量的值。 目录 一、概念&#xff0c;基本类型的反射二、结构体类型的反射三、类别方法Kind()四、修改变量的值 一、概念&#xff0c;基本…...

利用Puppeteer-Har记录与分析网页抓取中的性能数据

引言 在现代网页抓取中&#xff0c;性能数据的记录与分析是优化抓取效率和质量的重要环节。本文将介绍如何利用Puppeteer-Har工具记录与分析网页抓取中的性能数据&#xff0c;并通过实例展示如何实现这一过程。 Puppeteer-Har简介 Puppeteer是一个Node.js库&#xff0c;提供…...

YOLOv5改进系列(1)——添加CBAM注意力机制

一、如何理解注意力机制 假设你正在阅读一本书&#xff0c;同时有人在你旁边说话。当你听到某些关键字时&#xff0c;比如“你的名字”或者“你感兴趣的话题”&#xff0c;你会自动把注意力从书上转移到他们的谈话上&#xff0c;尽管你并没有完全忽略书本的内容。这就是注意力机…...

无头单向非循环java版的模拟实现

【本节目标】 1.ArrayList的缺陷 2.链表 1. ArrayList的缺陷 上节课已经熟悉了 ArrayList 的使用&#xff0c;并且进行了简单模拟实现。通过源码知道&#xff0c; ArrayList 底层使用数组来存储元素&#xff1a; public class ArrayList<E> extends AbstractList<…...

Bert Score-文本相似性评估

Bert Score Bert Score 是基于BERT模型的一种方法。它通过计算两个句子在BERT模型中的嵌入编码之间的余弦相似度来评估它们的相似度。BERTScore考虑了上下文信息和语义信息&#xff0c;因此能够更准确地衡量句子之间的相似度。 安装 pip install bert-score 使用例子 一个…...

Pyenv管理Python版本,conda之外的另一套python版本管理解决方案

简介 Pyenv 是一个 python 解释器管理工具&#xff0c;可以对计算机中的多个 python 版本进行管理和切换。为什么要用 pyenv 管理python呢&#xff0c;用过的 python 人都知道&#xff0c;python 虽然是易用而强大的编程语言&#xff0c;但是 python 解释器却有多个版本&#…...

快速实现AI搜索!Fivetran 支持 Milvus 作为数据迁移目标

Fivetran 现已支持 Milvus 向量数据库作为数据迁移的目标&#xff0c;能够有效简化 RAG 应用和 AI 搜索中数据源接入的流程。 数据是 AI 应用的支柱&#xff0c;无缝连接数据是充分释放数据潜力的关键。非结构化数据对于企业搜索和检索增强生成&#xff08;RAG&#xff09;聊天…...

css的页面布局属性

CSS Flexbox&#xff08;Flexible Box Layout&#xff09;是一种用于页面布局的CSS3规范&#xff0c;它提供了一种更加高效的方式来布置、对齐和分配容器内元素的空间&#xff0c;即使它们的大小是未知或者动态变化的。Flexbox很容易处理一维布局&#xff0c;即在一个方向上&am…...

RTE 大会报名丨AI 时代新基建:云边端架构和 AI Infra ,RTE2024 技术专场第二弹!

所有 AI Infra 都在探寻规格和性能的最佳平衡&#xff0c;如何构建高可用的云边端协同架构&#xff1f; 语音 AI 实现 human-like 的最后一步是什么&#xff1f; AI 视频的爆炸增长&#xff0c;给新一代编解码技术提出了什么新挑战&#xff1f; 当大模型进化到实时多模态&am…...

【React】入门Day01 —— 从基础概念到实战应用

目录 一、React 概述 二、开发环境创建 三、JSX 基础 四、React 的事件绑定 五、React 组件基础使用 六、组件状态管理 - useState 七、组件的基础样式处理 快速入门 – React 中文文档 一、React 概述 React 是什么 由 Meta 公司开发&#xff0c;是用于构建 Web 和原生…...

<<机器学习实战>>10-11节笔记:生成器与线性回归手动实现

10生成器与python实现 如果是曲线规律的数据集&#xff0c;则需要把模型变复杂。如果是噪音较大&#xff0c;则需要做特征工程。 随机种子的知识点补充&#xff1a; 根据不同库中的随机过程&#xff0c;需要用对应的随机种子&#xff1a; 比如 llist(range(5)) random.shuf…...

链表OJ经典题目及思路总结(一)

目录 前言1.移除元素1.1 链表1.2 数组 2.双指针2.1 找链表的中间结点2.2 找倒数第k个结点 总结 前言 解代码题 先整体&#xff1a;首先数据结构链表的题一定要多画图&#xff0c;捋清问题的解决思路&#xff1b; 后局部&#xff1a;接着考虑每一步具体如何实现&#xff0c;框架…...

初识chatgpt

GPT到底是什么 首先&#xff0c;我们需要了解GPT的全称&#xff1a;Generative Pre-trained Transformer&#xff0c;即三个关键词&#xff1a;生成式 预训练 变换模型。 &#xff08;1&#xff09;什么是生成式&#xff1f; 即能够生成新的文本序列。 &#xff08;2&#…...

【60天备战2024年11月软考高级系统架构设计师——第33天:云计算与大数据架构——大数据处理框架的应用场景】

随着大数据技术的发展&#xff0c;越来越多的企业开始采用大数据处理框架来解决实际问题。理解这些框架的应用场景对于架构师来说至关重要。 大数据处理框架的应用场景 实时数据分析&#xff1a;使用Apache Kafka与Apache Spark结合&#xff0c;可以实现对实时数据流的处理与…...

如何设计具体项目的数据库管理

### 例三&#xff1a;足协的数据库管理算法 #### 角色&#xff1a; - **ESFP学生**&#xff1a;小明 - **ENTP老师**&#xff1a;张老师 #### 主题&#xff1a;足协的数据库管理算法 --- **张老师**&#xff1a;小明&#xff0c;今天我们来讨论一下足协的数据库管理算法。你…...

对于 Vue CLI 项目如何引入Echarts以及动态获取数据

&#x1f680;个人主页&#xff1a;一颗小谷粒 &#x1f680;所属专栏&#xff1a;Web前端开发 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 1、数据画卷—Echarts介绍 1.1 什么是Echarts&#xff1f; 1.2 Echarts官网地址 2、Vue CLI 项目…...

【Linux笔记】在VMware中,为基于NAT模式运行的CentOS虚拟机设置固定的网络IP地址

一、配置VMware虚拟网络 1、打开VMware虚拟网络编辑器&#xff1a; 点击VMware主界面上方的“编辑”菜单&#xff0c;选择“虚拟网络编辑器”。 2、选择NAT模式网络&#xff1a; 在虚拟网络编辑器中&#xff0c;选择VMnet8&#xff08;或其他NAT模式的网络&#xff09;。 取消勾…...

一文上手Kafka【中】

一、发送消息细节 在发送消息的特别注意: 在版本 3.0 中&#xff0c;以前返回 ListenableFuture 的方法已更改为返回 CompletableFuture。为了便于迁移&#xff0c;2.9 版本添加了一个方法 usingCompletableFuture&#xff08;&#xff09;&#xff0c;该方法为 CompletableFu…...

Ubuntu如何如何安装tcpdump

在Ubuntu上安装tcpdump非常简单&#xff0c;可以通过以下步骤完成&#xff1a; 打开终端。 更新包列表&#xff1a; 首先&#xff0c;更新你的包管理器的包列表&#xff1a; sudo apt update 安装tcpdump&#xff1a; 使用以下命令安装tcpdump&#xff1a; sudo apt install …...

3-3 AUTOSAR RTE 对SR Port的作用

返回总目录->返回总目录<- 一、前言 RTE作为SWC和BSW之间的通信机构,支持Sender-Receiver方式实现ECU内及ECU间的通信。 对于Sender-Receiver Port支持三种模式: 显式访问:若运行实体采用显示模式的S/R通信方式,数据读写是即时的;隐式访问:当多个运行实体需要读取…...

Chrome for Testing 终极指南:5个实战技巧让自动化测试更稳定高效

Chrome for Testing 终极指南&#xff1a;5个实战技巧让自动化测试更稳定高效 【免费下载链接】chrome-for-testing 项目地址: https://gitcode.com/gh_mirrors/ch/chrome-for-testing Chrome for Testing 是 Google Chrome Labs 团队专门为浏览器自动化测试设计的 Chr…...

数据可视化:使用D3.js创建交互式图表

数据可视化&#xff1a;使用D3.js创建交互式图表 大家好&#xff0c;我是欧阳瑞&#xff08;Rich Own&#xff09;。今天想和大家聊聊数据可视化这个话题。作为一个全栈开发者&#xff0c;我经常需要将复杂的数据以直观的方式展示给用户。D3.js是一个功能强大的数据可视化库&am…...

三维姿态表达:从欧拉角、旋转矩阵到四元数的工程实践

1. 三维姿态表达的基础概念 在三维空间中描述物体的姿态&#xff08;orientation&#xff09;是许多工程领域的核心需求&#xff0c;无论是卫星姿态控制、机器人运动规划&#xff0c;还是游戏开发中的角色动画&#xff0c;都需要精确的姿态表达方式。姿态描述的本质是回答一个问…...

Excel公式生成黑科技落地实录(ChatGPT+Power Query+LAMBDA三引擎联动)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Excel公式生成黑科技落地实录&#xff08;ChatGPTPower QueryLAMBDA三引擎联动&#xff09; 场景驱动的智能公式生成闭环 当财务团队需在5分钟内为127张销售报表动态生成「跨表多条件加权滚动同比」公…...

【Microsystems Nanoengineering】利用多功能液晶偏振光栅抑制微型光学泵浦磁力计中的激光功率噪声

【Microsystems &Nanoengineering】利用多功能液晶偏振光栅抑制微型光学泵浦磁力计中的激光功率噪声 摘要 传统单光束光泵磁力仪&#xff08;OPM&#xff09;依赖分立偏振光学元件&#xff0c;体积大、装调复杂&#xff0c;且易受激光功率噪声限制。 本文提出 ** 多功能液晶…...

基于CircuitPython与BLE的智能振动腕带:从硬件选型到代码实现

1. 项目概述&#xff1a;打造你的智能触觉腕上伴侣如果你和我一样&#xff0c;经常被淹没在手机通知的海洋里&#xff0c;或者在专注工作时完全忘记了时间&#xff0c;那么这个项目可能就是为你量身定做的。今天&#xff0c;我们来动手制作一个基于CircuitPython和蓝牙低功耗&a…...

2026 汽车运动权威盘点:历史悠久、级别最高的标杆赛事解读

在汽车产业飞速发展的今天&#xff0c;汽车运动早已超越单纯的竞技比拼&#xff0c;成为彰显工业实力、传递汽车文化、连接产业与消费者的重要桥梁。2026 年&#xff0c;全球汽车运动市场持续升温&#xff0c;国际顶级赛事与国内标杆赛事同频共振、百花齐放。而那些历史悠久、级…...

如何快速修复分区表:开源数据恢复工具的完整指南

如何快速修复分区表&#xff1a;开源数据恢复工具的完整指南 【免费下载链接】testdisk TestDisk & PhotoRec 项目地址: https://gitcode.com/gh_mirrors/te/testdisk 你是否曾因为误删除重要文件而懊恼不已&#xff1f;是否遇到过分区丢失导致数据无法访问的困境&a…...

AI驱动的计划驱动开发:Gemini Plan Commands深度解析与实践指南

1. 项目概述&#xff1a;当AI工程师遇上“计划指挥官” 如果你是一名开发者&#xff0c;尤其是经常和AI模型打交道的工程师&#xff0c;你肯定遇到过这样的场景&#xff1a;面对一个复杂的代码库&#xff0c;你想快速理解它的架构&#xff1b;或者接到一个新功能需求&#xff…...

明日方舟游戏资源库:一站式高清素材解决方案

明日方舟游戏资源库&#xff1a;一站式高清素材解决方案 【免费下载链接】ArknightsGameResource 明日方舟客户端素材 项目地址: https://gitcode.com/gh_mirrors/ar/ArknightsGameResource 还在为创作明日方舟同人内容却找不到高质量素材而烦恼吗&#xff1f;想要开发明…...