Golang:reflect反射的使用例子
1.reflect包作用
reflect包定义了“反射”相关能力,“反射”在计算机学中是指计算机程序在运行时(runtime)可以访问、检测和修改它本身状态或行为的一种能力。基于反射特性可以通用化地解决一些需要频繁修改代码及硬编码问题,但是执行效率会被降低。
2.核心API
参考官方文档:https://pkg.go.dev/reflect#pkg-functions
3.使用案例
3.1.类型判断
- 用途:判断接口属于某种类型后进行特定处理
- 主要使用:TypeOf、Kind
type User struct {Name stringAge int
}type IUserService interface {GetUser(userID int64) User
}func reflectType() {var (intType intstringType *stringmapType map[string]interface{}structType *UserinterfaceType IUserService)var types []interface{}types = append(types, intType)types = append(types, stringType)types = append(types, mapType)types = append(types, structType)types = append(types, interfaceType)// 类型判断for i, v := range types {rtyp := reflect.TypeOf(v)if rtyp == nil {fmt.Printf("(%v)类型获取Type为nil,跳过\n", i)continue}rkind := rtyp.Kind()// 如果为指针类型,还原出真实类型if rtyp.Kind() == reflect.Ptr {fmt.Printf("(%v)指针类型: %v\n", i, rkind.String())rtyp = rtyp.Elem()}rkind = rtyp.Kind()fmt.Printf("(%v)类型%v\n", i, rkind.String())}
}
输出:
(0)类型int
(1)指针类型: ptr
(1)类型string
(2)类型map
(3)指针类型: ptr
(3)类型struct
(4)类型获取Type为nil,跳过
3.2.变量值获取
- 用于:获取类型的值
- 主要使用:ValueOf、Kind
func reflectValue() {var (intType int = 10stringType string = "hello world"mapType map[string]interface{} = nil)var types []interface{}types = append(types, intType)types = append(types, stringType)types = append(types, mapType)// 类型判断for i, v := range types {rval := reflect.ValueOf(v)if rval.Kind() == reflect.Ptr {rval = rval.Elem()}fmt.Printf("(%v)的值%v\n", i, rval.Interface())}
}
输出:
(0)的值10
(1)的值hello world
(2)的值map[]
3.3.遍历结构体的字段及值
- 用途:遍历未知类型结构体的字段及值,避免硬编码结构体处理
- 主要使用:TypeOf、ValueOf、NumField
func rangeStruct() {u := User{Name: "arong",Age: 23,Favors: []Favor{{Name: "篮球",ID: 1,},{Name: "唱跳",ID: 2,},{Name: "RAP",ID: 3,},},}rval := reflect.ValueOf(&u)if rval.Kind() == reflect.Ptr {rval = rval.Elem()}for i := 0; i < rval.NumField(); i++ {name := rval.Type().Field(i).Nameval := rval.Field(i).Interface()fmt.Printf("字段%v值为%v\n", name, val)}
}
输出:
字段Name值为arong
字段Age值为23
字段Favors值为[{篮球 1} {唱跳 2} {RAP 3}]
3.4.结构体字段赋值
- 用途:对未知结构体的特定字段进行赋值
- 主要使用:ValueOf、FieldByName、CanSet、Set
func reflectSetValue() {u := User{Name: "arong",Age: 23,}fmt.Printf("原始字段值:%#v\n", u)// 一定要取指针,不然无法赋值rval := reflect.ValueOf(&u).Elem()rvalNameField := rval.FieldByName("Name")// 字段是否可写入if rvalNameField.CanSet() {rvalNameField.Set(reflect.ValueOf("pbrong"))}fmt.Printf("改变已知字段值:%#v\n", u)
}
3.5.函数及方法调用
- 用途:使用反射动态调用指定函数及方法
- 主要使用:
type User struct {Name stringAge intFavors []Favor
}type IUserService interface {GetUser(userID int64) User
}type UserService struct {
}func (u *UserService) GetUser(userID int64) User {user := User{Name: "defaultTestUser",Age: -1,Favors: []Favor{},}fmt.Printf("GetUser exec: result = %#v\n", user)return user
}func TestFunc(names string) {fmt.Printf("TestFunc exec: result = %v\n", names)
}func reflectSetValue() {u := User{Name: "arong",Age: 23,}fmt.Printf("原始字段值:%#v\n", u)// 一定要取指针,不然无法赋值rval := reflect.ValueOf(&u).Elem()rvalNameField := rval.FieldByName("Name")// 字段是否可写入if rvalNameField.CanSet() {rvalNameField.Set(reflect.ValueOf("pbrong"))}fmt.Printf("改变已知字段值:%#v\n", u)
}
输出:
TestFunc exec: result = pbrong
GetUser exec: result = main.User{Name:"defaultTestUser", Age:-1, Favors:[]main.Favor{}}
GetUser resp: main.User{Name:"defaultTestUser", Age:-1, Favors:[]main.Favor{}}
4.避免滥用反射
反射使用不当可能会影响程序的性能和可读性。因此,在 Go 中,我们通常建议尽可能地避免滥用反射。
主要的原因是,反射的本质是一种运行时类型转换,会导致一定的开销。因为它需要动态地获取类型信息,进行类型检查,以及在运行时动态地分配内存等。这些操作都比静态类型转换需要更多的计算资源和时间。
另外,由于反射的使用不够直观和简洁,可能会降低代码的可读性和可维护性。特别是当开发人员不了解反射的工作原理时,容易出现一些难以调试和排查的问题。
因此,通常情况下我们应该尽可能地避免滥用反射。只有在必要的场景下才使用反射,例如需要在运行时动态地创建对象、调用函数、解析数据等。在其他场景下,我们应该尽可能使用 Go 的静态类型系统和语言特性,使得代码更加简洁、高效和可读。
相关文章:
Golang:reflect反射的使用例子
1.reflect包作用 reflect包定义了“反射”相关能力,“反射”在计算机学中是指计算机程序在运行时(runtime)可以访问、检测和修改它本身状态或行为的一种能力。基于反射特性可以通用化地解决一些需要频繁修改代码及硬编码问题,但是…...
markdown常用语法--花括号(超详细)
💌 所属专栏:【Markdown常用语法】 😀 作 者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! …...
BN、SyncBN、IN、LN、GN学习记录
1 BatchNormBN的原理BN是计算机视觉最常用的标准化方法,它沿着N、H、W维度对输入特征图求均值和方差,随后再利用均值和方差来归一化特征图。计算过程如下图所示,1)沿着通道维度计算其他维度的均值;2)沿着通…...
使用 Auto-scheduling 优化算子
本篇回答来源于 TVM 官方英文文档 Lianmin Zheng,Chengfan Jia。更多 TVM 中文文档可访问→https://tvm.hyper.ai/ 本教程将展示 TVM 的 Auto Scheduling 功能,如何在不编写自定义模板的情况下,找到最佳 schedule。 与基于模板的 AutoTVM 依…...
智能运维应用之道,告别企业数字化转型危机
面临的问题及挑战 数据中心发展历程 2000 年中国数据中心始建,至今已经历以下 3 大阶段。早期:离散型数据中心 IT 因以项目建设为导向,故缺乏规划且无专门运维管理体系,此外,开发建设完的项目均是独立运维维护&#…...
第七章 SQL错误信息 - SQL错误代码 -400 到 -500
文章目录第七章 SQL错误信息 - SQL错误代码 -400 到 -500SQL错误代码和消息表WinSock错误代码-10050到-11002第七章 SQL错误信息 - SQL错误代码 -400 到 -500 SQL错误代码和消息表 错误代码描述-400发生严重错误-401严重连接错误-402用户名/密码无效-405无法从通信设备读取-4…...
DDFN: Decoupled Dynamic Filter Networks解耦的动态卷积
一、论文信息 论文名称:Decoupled Dynamic Filter Networks 论文:https://thefoxofsky.github.io/files/ddf.pdf 代码:https://github.com/theFoxofSky/ddfnet 主页:https://thefoxofsky.github.io/project_pages/ddf 作者团…...
NISP认证报名条件是什么?考试内容是什么?
科学技术是社会发展的第一生产力,每个国家为了能够获得更高的国际地位,不断提升自己的科学技术,现代最为先进的技术就是信息通信,在军事、民生、医疗、教育、制造等等领域都起着重要的作用,我们的生活也因为信息技术而…...
利用redis实现缓存、发布订阅、分布式锁功能
Redis是一个内存键值存储数据库,通常用于缓存、会话管理、消息队列等场景。以下是一些常见的Redis使用场景:1.缓存:将常用的数据缓存在Redis中,以减少对数据库的访问次数,提高应用程序的性能。2.会话管理:使…...
SVN无法连接到服务器的各种问题原因及解决办法
SVN专业使用教程详解 第一节 安装VisualSVN Server服务器 第一步 下载SVN服务器,需要链接的请私信。 点击下载的执行文档进行安装 选择组件 选择在部署 VisualSVN Server 时安装VisualSVN Server 和 Administration Tools 组件。 调整初始服务器配置 或者&…...
React 基本使用
目录 React 安装 React基本使用 React脚手架 脚手架使用React JSX基本使用 JSX列表渲染 JSX条件渲染 JSX模板精简 JSX样式控制 JSX综合案例 React 安装 npm i react react-domnpm init -y(生成基础目录文件) <!-- 引入js文件 --><sc…...
单例模式设计(面试题)
1、static修饰变量规则static修饰的静态成员属于 类而不是对象,所有的对象共享一份静态成员数据,所以不占用类的空间static修饰的成员,定义类的时候,必须分配空间static修饰的静态成员数据 必须类中定义 类外初始化静态成员变量可…...
机器学习:基于支持向量机(SVM)进行人脸识别预测
机器学习:基于支持向量机(SVM)进行人脸识别预测 文章目录机器学习:基于支持向量机(SVM)进行人脸识别预测一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤1.准备数据2.业务理解3.数据理解4.数…...
【服务器数据恢复】多块磁盘离线导致RAIDZ崩溃的数据恢复案例
服务器数据恢复环境: SUN ZFS系列某型号存储阵列; 40块磁盘组建的存储池(其中4块磁盘用作全局热备盘),池内划分出若干空间映射到服务器使用; 服务器使用Windows操作系统。 服务器故障: 服务器在…...
iconfont 图标如何在uniapp中的tabBar使用
注意: 小程序并不支持tabBar中 设置 iconfont 1. 材料准备 首先进入字体图标网址:iconfont-阿里巴巴矢量图标库;(如果你没有登入,记得登入一下) 把图标添加入购物车 添加到购物车之后-(右上角…...
第六章.卷积神经网络(CNN)—卷积层(Convolution)池化层(Pooling)
第六章.卷积神经网络(CNN) 6.1 卷积层(Convolution)&池化层(Pooling) 1.整体结构 以5层神经网络的实现为例: 1).基于全连接层(Affine)的网络 全连接层:相邻层的所有神经元之间都有连接 2).常见的CNN的网络 3).全连接层存在的问题 数据的形状容易被…...
c/c++开发,无可避免的模板编程实践(篇六)
一、泛型算法 1.1 泛型算法概述 c标准库不仅包含数据结构(容器、容器适配器等),还有很多算法。数据结构可以帮助存放特定情况下需要保存的数据,而算法则会将数据结构中存储的数据进行变换。标准库没有给容器添加大量的功能函数&am…...
【Java】Spring核心与设计思想
文章目录Spring核心与设计思想1. Spring是什么1.1 什么是容器1.2 什么是IOC1.2.1 传统程序开发1.2.2 控制反转式程序开发1.2.3 对比总结规律1.3 理解Spring IOC1.4 DI概念说明Spring核心与设计思想 1. Spring是什么 我们通常所说的Spring指的是Spring Framework(S…...
组合实现多类别分割(含实战代码)
来源:投稿 作者:AI浩 编辑:学姐 摘要 segmentation_models_pytorch是一款非常优秀的图像分割库,albumentations是一款非常优秀的图像增强库,这篇文章将这两款优秀结合起来实现多类别的图像分割算法。数据集选用CamVid…...
从红队视角看AWD攻击
AWD的权限维持 攻防兼备AWD模式是一种综合考核参赛团队攻击、防御技术能力、即时策略的比赛模式。在攻防模式中,参赛队伍分别防守同样配置的虚拟靶机,并在有限的博弈时间内,找到其他战队的薄弱环节进行攻击,同时要对自己的靶机环…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...
