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

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包定义了“反射”相关能力&#xff0c;“反射”在计算机学中是指计算机程序在运行时&#xff08;runtime&#xff09;可以访问、检测和修改它本身状态或行为的一种能力。基于反射特性可以通用化地解决一些需要频繁修改代码及硬编码问题&#xff0c;但是…...

markdown常用语法--花括号(超详细)

&#x1f48c; 所属专栏&#xff1a;【Markdown常用语法】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1…...

BN、SyncBN、IN、LN、GN学习记录

1 BatchNormBN的原理BN是计算机视觉最常用的标准化方法&#xff0c;它沿着N、H、W维度对输入特征图求均值和方差&#xff0c;随后再利用均值和方差来归一化特征图。计算过程如下图所示&#xff0c;1&#xff09;沿着通道维度计算其他维度的均值&#xff1b;2&#xff09;沿着通…...

使用 Auto-scheduling 优化算子

本篇回答来源于 TVM 官方英文文档 Lianmin Zheng&#xff0c;Chengfan Jia。更多 TVM 中文文档可访问→https://tvm.hyper.ai/ 本教程将展示 TVM 的 Auto Scheduling 功能&#xff0c;如何在不编写自定义模板的情况下&#xff0c;找到最佳 schedule。 与基于模板的 AutoTVM 依…...

智能运维应用之道,告别企业数字化转型危机

面临的问题及挑战 数据中心发展历程 2000 年中国数据中心始建&#xff0c;至今已经历以下 3 大阶段。早期&#xff1a;离散型数据中心 IT 因以项目建设为导向&#xff0c;故缺乏规划且无专门运维管理体系&#xff0c;此外&#xff0c;开发建设完的项目均是独立运维维护&#…...

第七章 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解耦的动态卷积

一、论文信息 论文名称&#xff1a;Decoupled Dynamic Filter Networks 论文&#xff1a;https://thefoxofsky.github.io/files/ddf.pdf 代码&#xff1a;https://github.com/theFoxofSky/ddfnet 主页&#xff1a;https://thefoxofsky.github.io/project_pages/ddf 作者团…...

NISP认证报名条件是什么?考试内容是什么?

科学技术是社会发展的第一生产力&#xff0c;每个国家为了能够获得更高的国际地位&#xff0c;不断提升自己的科学技术&#xff0c;现代最为先进的技术就是信息通信&#xff0c;在军事、民生、医疗、教育、制造等等领域都起着重要的作用&#xff0c;我们的生活也因为信息技术而…...

利用redis实现缓存、发布订阅、分布式锁功能

Redis是一个内存键值存储数据库&#xff0c;通常用于缓存、会话管理、消息队列等场景。以下是一些常见的Redis使用场景&#xff1a;1.缓存&#xff1a;将常用的数据缓存在Redis中&#xff0c;以减少对数据库的访问次数&#xff0c;提高应用程序的性能。2.会话管理&#xff1a;使…...

SVN无法连接到服务器的各种问题原因及解决办法

SVN专业使用教程详解 第一节 安装VisualSVN Server服务器 第一步 下载SVN服务器&#xff0c;需要链接的请私信。 点击下载的执行文档进行安装 选择组件 选择在部署 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&#xff08;生成基础目录文件&#xff09; <!-- 引入js文件 --><sc…...

单例模式设计(面试题)

1、static修饰变量规则static修饰的静态成员属于 类而不是对象&#xff0c;所有的对象共享一份静态成员数据&#xff0c;所以不占用类的空间static修饰的成员&#xff0c;定义类的时候&#xff0c;必须分配空间static修饰的静态成员数据 必须类中定义 类外初始化静态成员变量可…...

机器学习:基于支持向量机(SVM)进行人脸识别预测

机器学习&#xff1a;基于支持向量机&#xff08;SVM&#xff09;进行人脸识别预测 文章目录机器学习&#xff1a;基于支持向量机&#xff08;SVM&#xff09;进行人脸识别预测一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤1.准备数据2.业务理解3.数据理解4.数…...

【服务器数据恢复】多块磁盘离线导致RAIDZ崩溃的数据恢复案例

服务器数据恢复环境&#xff1a; SUN ZFS系列某型号存储阵列&#xff1b; 40块磁盘组建的存储池&#xff08;其中4块磁盘用作全局热备盘&#xff09;&#xff0c;池内划分出若干空间映射到服务器使用&#xff1b; 服务器使用Windows操作系统。 服务器故障&#xff1a; 服务器在…...

iconfont 图标如何在uniapp中的tabBar使用

注意&#xff1a; 小程序并不支持tabBar中 设置 iconfont 1. 材料准备 首先进入字体图标网址&#xff1a;iconfont-阿里巴巴矢量图标库&#xff1b;&#xff08;如果你没有登入&#xff0c;记得登入一下&#xff09; 把图标添加入购物车 添加到购物车之后-&#xff08;右上角…...

第六章.卷积神经网络(CNN)—卷积层(Convolution)池化层(Pooling)

第六章.卷积神经网络(CNN) 6.1 卷积层(Convolution)&池化层(Pooling) 1.整体结构 以5层神经网络的实现为例&#xff1a; 1).基于全连接层(Affine)的网络 全连接层&#xff1a;相邻层的所有神经元之间都有连接 2).常见的CNN的网络 3).全连接层存在的问题 数据的形状容易被…...

c/c++开发,无可避免的模板编程实践(篇六)

一、泛型算法 1.1 泛型算法概述 c标准库不仅包含数据结构&#xff08;容器、容器适配器等&#xff09;&#xff0c;还有很多算法。数据结构可以帮助存放特定情况下需要保存的数据&#xff0c;而算法则会将数据结构中存储的数据进行变换。标准库没有给容器添加大量的功能函数&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&#xff08;S…...

组合实现多类别分割(含实战代码)

来源&#xff1a;投稿 作者&#xff1a;AI浩 编辑&#xff1a;学姐 摘要 segmentation_models_pytorch是一款非常优秀的图像分割库&#xff0c;albumentations是一款非常优秀的图像增强库&#xff0c;这篇文章将这两款优秀结合起来实现多类别的图像分割算法。数据集选用CamVid…...

从红队视角看AWD攻击

AWD的权限维持 攻防兼备AWD模式是一种综合考核参赛团队攻击、防御技术能力、即时策略的比赛模式。在攻防模式中&#xff0c;参赛队伍分别防守同样配置的虚拟靶机&#xff0c;并在有限的博弈时间内&#xff0c;找到其他战队的薄弱环节进行攻击&#xff0c;同时要对自己的靶机环…...

Steam美区支付实战:巧用虚拟VISA与PayPal组合策略,解锁游戏购买与礼品卡赠送

1. Steam美区支付的核心痛点与解决方案 很多玩家都遇到过这样的问题&#xff1a;好不容易注册了美区Steam账号&#xff0c;却发现国内的信用卡根本无法完成支付。我自己刚开始折腾美区账号时&#xff0c;也在这个环节卡了整整两周。Steam的风控机制确实严格得令人头疼&#xff…...

万象视界灵坛惊艳效果:CLIP-ViT-L/14在低分辨率图像上的鲁棒性语义解析

万象视界灵坛惊艳效果&#xff1a;CLIP-ViT-L/14在低分辨率图像上的鲁棒性语义解析 1. 平台概览与核心价值 万象视界灵坛是一款基于OpenAI CLIP-ViT-L/14模型构建的多模态智能感知平台。不同于传统视觉识别系统的单调界面&#xff0c;这个平台将复杂的语义对齐过程转化为直观…...

DeepSeek linux-6.19/kernel/events/ring_buffer.c 源码分析

我来分析 Linux 6.19 内核中 kernel/events/ring_buffer.c 的源码。这个文件实现了 perf events 子系统的环形缓冲区管理&#xff0c;用于在内核和用户空间之间高效传递性能事件数据。 文件概述 ring_buffer.c 是 perf events 系统的核心组件&#xff0c;负责管理用于存储性能事…...

在 AMD Ryzen AI 7 H350 Radeon 860M 上使用 Ollama 运行 GPU 加速

本文介绍了如何在搭载 AMD Ryzen AI 7 H350 及 Radeon 860M 显卡的系统上&#xff0c;配置 Ollama 以利用 GPU 运行 AI 模型。 一、安装 AMD 驱动程序 首先&#xff0c;请安装最新的 AMD 驱动程序&#xff0c;以确保系统能够正确识别并调用显卡硬件。 驱动程序下载地址&…...

VSCode 中使用 MATLAB 安装流程

文章目录 运行程序 修改 Code-Runner 文件 使用 Copilot 如何开启 MATLAB 调试功能 Matlab: Linter Config(代码检查器配置):保持空白就好。 Linter(在这里指的是 MATLAB 的 mlint)是一个静态代码分析工具。它会在你写代码时,自动用波浪线提示语法错误或者给出优化建议(…...

MATLAB三维绘图实战:用plot3和fplot3函数搞定螺旋线与墨西哥帽(附完整代码)

MATLAB三维绘图实战&#xff1a;螺旋线与墨西哥帽的视觉盛宴 在工程计算与科学可视化领域&#xff0c;MATLAB始终保持着不可替代的地位。当二维平面无法完整表达数据的内在规律时&#xff0c;三维图形便成为洞察复杂关系的利器。本文将带您深入探索MATLAB中两大三维曲线绘制神器…...

MacBook安装OpenClaw避坑指南:Qwen3-14B镜像对接常见问题

MacBook安装OpenClaw避坑指南&#xff1a;Qwen3-14B镜像对接常见问题 1. 为什么选择OpenClawQwen3-14B组合 去年底我开始尝试用AI自动化处理日常办公任务时&#xff0c;发现大多数方案要么需要将敏感数据上传到云端&#xff0c;要么功能过于局限。直到遇到OpenClaw这个开源框…...

WTF, forms? CSS原理大揭秘:如何用纯CSS打造自定义表单控件

WTF, forms? CSS原理大揭秘&#xff1a;如何用纯CSS打造自定义表单控件 【免费下载链接】wtf-forms Friendlier HTML form controls with a little CSS magic. 项目地址: https://gitcode.com/gh_mirrors/wt/wtf-forms WTF, forms? 是一个通过纯CSS魔法打造友好HTML表…...

Java程序设计(第3版)第二章——变量的三种定义方式2和3

变量的第二种使用方式 在声明的同时并赋值 数据类型 变量名 &#xff1d; 数据; int b &#xff1d; 12; System.out.println(b); 输出为12变量的第三种使用方式 同时定义多个同类型变量 int c,d&#xff1d;1,e&#xff1d;11,f&#xff1d;23,g&#xff1d;32,h&#xff1d;0…...

避坑指南:ESP32-S3驱动ILI9488屏显示OV2640画面,这些时序和内存问题你遇到了吗?

ESP32-S3驱动ILI9488屏显示OV2640画面的五大实战避坑指南 当你在ESP32-S3上整合OV2640摄像头和ILI9488显示屏时&#xff0c;可能会遇到各种令人抓狂的问题——从花屏、卡顿到系统崩溃。这篇文章不会重复那些基础接线和库安装步骤&#xff0c;而是直击核心痛点&#xff0c;分享我…...