当前位置: 首页 > 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通信方式,数据读写是即时的;隐式访问:当多个运行实体需要读取…...

hive/impala/mysql几种数据库的sql常用写法和函数说明

做大数据开发的时候&#xff0c;会在几种库中来回跳&#xff0c;同一个需求&#xff0c;不同库函数和写法会有出入&#xff0c;在此做汇总沉淀。 1. hive 1. 日期差 DATEDIFF(CURRENT_DATE(),wdjv.creation_date) < 30 30天内的数据 2.impala 3. spark 4. mysql 1.时间差…...

论文阅读:LM-Cocktail: Resilient Tuning of Language Models via Model Merging

论文链接 代码链接 Abstract 预训练的语言模型不断进行微调,以更好地支持下游应用。然而,此操作可能会导致目标领域之外的通用任务的性能显著下降。为了克服这个问题,我们提出了LM Cocktail,它使微调后的模型在总体上保持弹性。我们的方法以模型合并(Model Merging)的形…...

8640 希尔(shell)排序

### 思路 希尔排序是一种基于插入排序的排序算法&#xff0c;通过将待排序数组分割成多个子序列分别进行插入排序来提高效率。初始增量d为n/2&#xff0c;之后每次减半&#xff0c;直到d为1。 ### 伪代码 1. 读取输入的待排序关键字个数n。 2. 读取n个待排序关键字并存储在数组…...

Linux 安装redis主从模式+哨兵模式3台节点

下载 https://download.redis.io/releases/ 解压 tar -zxvf redis-7.2.4.tar.gz -C /opt chmod 777 -R /opt/redis-7.2.4/安装 # 编译 make # 安装&#xff0c; 一定是大写PREFIX make PREFIX/opt/redis-7.2.4/redis/ install配置为系统服务 cd /etc/systemd/system/主服务…...

[BCSP-X2024.小高3] 学习计划

题目描述 暑假共有 n 天&#xff0c;第 i 天的精力指数为 a[i]&#xff0c;你想要利用假期依次&#xff08;按 1,2,...,m 顺序&#xff09;复习 m 门功课&#xff0c;第 i 门功课的重要程度为 b[i]&#xff0c;且每门的复习时段必须连 续&#xff0c;并且不能有某天不干事。 …...

Android Debug Bridge(ADB)完全指南

文章目录 前言一、什么是ADB&#xff1f;二、ADB的工作原理ADB由三个部分组成&#xff1a; 三、如何安装ADBWindows系统&#xff1a;macOS和Linux系统&#xff1a; 四、ADB常用指令大全设备相关操作1. 查看连接的设备&#xff1a;2. 重启设备&#xff1a;3. 进入Bootloader模式…...

再次重逢,愿遍地繁花

再次重逢&#xff0c;愿遍地繁花 我并不是一个对最终幻想7很热衷的粉丝&#xff0c;也并没有像那些评论区的大佬&#xff0c;能够轻易地说出整部世界的全貌。说到底&#xff0c;我只是一个看完了《最终幻想7&#xff1a;重制版》和《最终幻想7&#xff1a;重生》的爱好者罢了。…...

数据结构和算法基础(一)

文章目录 链表反转链表合并删除链表倒数第 n 个结点找链表的中间结点链表中环的检测排序算法递归 趁空闲时间刷一遍极客时间上王争的《数据结构与算法之美》课程&#xff0c;个人觉得写的很好&#xff0c;每章节由浅入深且从基础到引入设计类问题&#xff0c;如果写过很多代码想…...

【超长好文】网络安全从业者面试指南

文章为笔者偶然看到的github项目《网络安全面试指南》&#xff0c;作者FeeiCN&#xff0c;读完内容深感作者的用心&#xff0c;尽管一些观点因为时间原因与当下行情存在差异&#xff0c;但仍旧值得大家参考&#xff0c;希望能给大家在这行业寒冬带来一些启发&#xff0c;愿正在…...

基于大数据的高校新生数据可视化分析系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

网站当前位置怎么做/网络推广员每天的工作是什么

HTML 速查列表. 你可以可以打印它&#xff0c;以备日常使用。HTML 基本文档文档标题基本标签(Basic Tags)最大的标题. . . . . . . . . . . . 最小的标题这是一个段落。(换行)(水平线)文本格式化(Formatting)粗体文本计算机代码强调文本斜体文本键盘输入预格式化文本更小的文本…...

网站制作的地方/网络营销服务商

静态字段缓存基本使用 /// <summary>/// 1 客户端缓存-CDN缓存-反向代理缓存-本地缓存/// 2 本地缓存原理和手写基础实现/// 3 缓存更新/过期/多线程测试 /// 4 缓存类库封装和缓存应用总结 /// </summary>/// <param name="args"></param&…...

政府门户网站建设的体现/怎么样建立自己的网站

Case when 的用法,简单Case函数 简单CASE表达式,使用表达式确定返回值. 语法: CASE search_expression WHEN expression1 THEN result1 WHEN expression2 THEN result2 ... WHEN expressionN THEN resultN ELSE default_result 搜索CASE表达式,使用条件确定返回值. 语法: CASE …...

烘焙食品网站建设需求分析/百度推广优化技巧

5.11.1找出3~100以内所有的素数 ##找出3~100以内所有素数 #&#xff08;1&#xff09;考虑初始条件 ##n 3 #(2)循环的结束条件 ##n<100 #(3)重复需要干什么 ##判断n是否为素数 #&#xff08;4&#xff09;如何度过下一次循环 ##nn1 n 3 while n<100:i 2flag True # …...

江西移动网站/广告公司职位

tidb在插入一个新数据的时候报错&#xff1a; Table has no partition for value xxx 表明表中没有这个分区&#xff0c;需要新增 查一下新增语句 ALTER TABLE fans_medal ADD PARTITION (PARTITION p20200828 VALUES LESS THAN (20200829));然后再插入我需要的数据 解决&…...

企业网站的推广方法/站内优化主要从哪些方面进行

如下图所示&#xff0c;我在任何时候按F1键&#xff0c;都会自动弹出Windows帮助和支持&#xff0c;事实上这个功能很鸡肋&#xff0c;从来没用过&#xff0c;但是玩魔兽的时候确实必须的&#xff0c;F1控制英雄的&#xff0c;呵呵。 方法还是有的&#xff0c;在任务管理器中找…...