golang反射

go反射

  • 反射
    • 基本介绍
    • 应用场景
    • 基本使用
    • 结构体
    • 注意
    • 练习
    • 最佳实践
      • 遍历结构体的方法,调用接头体的方法,获取结构体的标签

反射

基本介绍

  1. 反射可以在运行时动态获取变量的各种信息,比如变量的类型(type)、类别(kind)
  2. 如果是结构体变量,可以获取到结构体本身的信息(包括结构体的字段、方法)
  3. 通过反射,可以修改变量的值,可以调用关联的方法
  4. 使用反射,需要import(“reflect”)
  5. 示意图
    在这里插入图片描述

应用场景

  1. reflect.TypeOf(变量名) 获取变量的类型,返回reflect.Type类型
  2. reflect.ValueOf(变量名)获取变量的值,返回reflect.Value 是一个结构体类型,通过reflect.Value,可以获取该变量的很多信息
  3. 变量、interface{} 和 reflect.Value 是可以相互转换的,这点在实际开发中经常会用到

基本使用


// 演示反射
func reflectTest01(b interface{}) {rTyp := reflect.TypeOf(b)fmt.Println("TypeOf", rTyp)fmt.Printf("TypeOf Type %T \n", rTyp)value := reflect.ValueOf(b)fmt.Println("ValueOf", value)fmt.Printf("ValueOf %T\n", value)fmt.Println(value.Int() + 13)// 将 rVal 转成interface{}iv := value.Interface()// 将 any 断言num2 := iv.(int)fmt.Println(num2)}func TestReflect(t *testing.T) {var num int = 100reflectTest01(num)
}

结构体


// 演示反射
func reflectTest01(stu Student) {stuType := reflect.TypeOf(stu)fmt.Println("stuType", stuType)fmt.Println("stuType Kind", stuType.Kind())stuValue := reflect.ValueOf(stu)fmt.Println("stuValue", stuValue)fmt.Println("stuValue Kind", stuValue.Kind())stuIv := stuValue.Interface()fmt.Printf("接口 类型 %T \n", stuIv)student, ok := stuIv.(Student)if ok {fmt.Printf("接口 类型 %T \n", student)}}type Student struct {Name stringAge  int
}func TestReflect(t *testing.T) {student := Student{"tom", 13,}reflectTest01(student)
}

注意

  1. reflect.Value.Kind 获取变量的类别,返回的是一个产量
  2. Type 是类型 Kind是类别,Type和Kind可能相同,可能不同
    比如:int Type :int ; Kind:int
    Student Type:Student ; Kind:struct
  3. 通过反射可以在让变量在 interface{} 和 Reflect.Value 之间相互转换
  4. 使用反射的方式来获取变量的值(并返回对应的类型),要求数据类型匹配,否则panic
  5. 通过反射修改变量,注意当使用setXxx方法来设置需要通过对应的指针来完成,同时需要使用reflect.Value.Elem
func TestReflect(t *testing.T) {i := 10iValue := reflect.ValueOf(&i)// 获取指针进行修改值iValue.Elem().SetInt(20)fmt.Println(i)
}

练习

func TestReflect(t *testing.T) {var v float64 = 1.2value := reflect.ValueOf(v)vType := value.Type()vKind := value.Kind()fmt.Println(vType, vKind, value)fv, ok := value.Interface().(float64)if ok {fmt.Printf("FV 的值 %v 类型 %T \n", fv, fv)}
}

最佳实践

遍历结构体的方法,调用接头体的方法,获取结构体的标签

func TestReflect(t *testing.T) {m := Monster{Name:  "黄书狼",Age:   400,Score: 30.8,}mType := reflect.TypeOf(m)mValue := reflect.ValueOf(m)if mValue.Kind() != reflect.Struct {fmt.Println("expect struct")return}num := mValue.NumField()fmt.Printf("struct has %d field \n", num)for i := 0; i < num; i++ {fmt.Printf("字段 %d 值为%v\n", i, mValue.Field(i))// 获取struct标签,注意需要通过reflect.Type 来获取tag标签的值tagVal := mType.Field(i).Tag.Get("json")if tagVal != "" {fmt.Printf("字段 %d : tag为%v\n", i, tagVal)}}methodNum := mValue.NumMethod()fmt.Printf("struct has %d method \n", methodNum)mValue.Method(1).Call(nil) // 按照名字的ASC码排序//mValue.MethodByName("Print").Call(nil)var params []reflect.Valueparams = append(params, reflect.ValueOf(10))params = append(params, reflect.ValueOf(40))res := mValue.Method(0).Call(params)fmt.Println("res ", res[0].Int())
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/318425.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式: 工厂模式

工厂模式&#xff08;Factory Pattern&#xff09;是 Java 中最常用的设计模式之一&#xff0c;这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 工厂模式提供了一种创建对象的方式&#xff0c;而无需指定要创建的具体类。 工厂模式属于创建型…

【Web】D^3CTF之浅聊d3pythonhttp——TE-CL请求走私

目录 step0 题目信息 step1 jwt空密钥伪造 step1.5 有关TE&CL的lab step2 TE-CL请求走私 payload1 payload2 step0 题目信息 注意到题目源码前端是flask写的&#xff0c;后端是web.py写的 frontend from flask import Flask, request, redirect, render_templat…

万界星空科技商业开源MES+项目合作+商业开源低代码平台

今天我想和大家分享的是一套商业开源的 MES制造执行管理系统带源码。对于制造业而言&#xff0c;MES 是一个至关重要的系统&#xff0c;它可以帮助企业提高生产效率、优化资源利用、提高产品质量&#xff0c;从而增强市场竞争力。 什么是 MES&#xff1f; MES 是指通过计算机技…

安装部署大语言模型 | 通义千问

下载安装 进入ollama的仓库下载 「 qwen 7b 」 libraryGet up and running with large language models.https://ollama.com/library查找阿里的 「 qwen 」 根据自己的电脑配置情况&#xff0c;选择合适的模型 总体来说&#xff0c;模型是越大&#xff0c;效果越好&#xff0c…

数据库(MySQL)基础:约束

一、概述 1.概念&#xff1a;约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。 2.目的&#xff1a;保证数据库中数据的正确、有效性和完整性。 3.分类 约束描述关键字非空约束限制该字段的数据不能为nullnot null唯一约束保证该字段的所有数据都是唯一…

JSP在页面用<%=调用声明函数时出现HTTP 500错误

JSP在页面用<%调用声明函数时出现HTTP 500错误 错误描述&#xff1a; Eclipse在编写JSP页面时&#xff0c;在其中采用<%&#xff01;%>方式声明了函数&#xff0c;然后在页面中用<%函数名%>方式调用时&#xff0c;出现HTTP状态500错误&#xff0c;提示为&#…

PC通过串口发送指令控制LED+串口中断

如何让单片机接收数据&#xff1f; 首先要打开SCON中的串行接收控制位REN。当REN1时为允许接收状态&#xff0c;可以接收信息。 因此令SCON 0x50&#xff1b; 怎么知道收到数据&#xff1f; 利用RI接收中断请求标志位。当串行接收到第8位结束时由内部硬件自动置为RI1&#…

LabVIEW机械臂控制与图像处理示教平台

LabVIEW机械臂控制与图像处理示教平台 随着工业自动化技术的快速发展&#xff0c;工业机器人在制造业中的应用越来越广泛&#xff0c;它们在提高生产效率、降低人工成本以及保证产品质量方面发挥着重要作用。然而&#xff0c;传统的工业机器人编程和操作需要专业知识&#xff…

Git使用指北

目录 创建一个Git仓库本地仓库添加文件文件提交到本地仓库缓冲区添加远程仓库地址本地仓库推送到远程仓库创建新的分支拉取代码同步删除缓冲区的文件&#xff0c;远程仓库的文件.gitignore文件 创建一个Git仓库 Git仓库分为远程和本地两种&#xff0c;远程仓库如Githu上创建的…

计算机网络之传输层TCP\UDP协议

UDP协议 用户数据报协议UDP概述 UDP只在IP数据报服务之上增加了很少功能&#xff0c;即复用分用和差错检测功能 UDP的主要特点&#xff1a; UDP是无连接的&#xff0c;减少开销和发送数据之前的时延 UDP使用最大努力交付&#xff0c;即不保证可靠交付&#xff0c;可靠性由U…

Debian 12 tomcat 9 catalina 日志信息 中文显示乱码

目录 问题现象 解决办法&#xff1a; 1、设定Debian locale 2、设定catalina.sh utf8字符集 问题现象 Debian 12 linux操作系统中&#xff0c;tomcat 9 catalina 启动日志输出 中文乱码 解决办法&#xff1a; 1、设定Debian locale 先确保系统本身就支持中文的 Debian …

免安装SQL管理工具HeidiSQL建库如何选Collation字符校对

免安装SQL管理工具HeidiSQL 文章目录 免安装SQL管理工具HeidiSQL一、安装二、建库因此&#xff0c;通常我们选择&#xff1a; 一、安装 到官方网址&#xff1a;https://www.heidisql.com/ 下载后按不同版本安装或解压&#xff0c;运行目录中的heidisql应用程序。 该工具可以对…

自动驾驶中的深度学习和计算机视觉

书籍&#xff1a;Applied Deep Learning and Computer Vision for Self-Driving Cars: Build autonomous vehicles using deep neural networks and behavior-cloning techniques 作者&#xff1a;Sumit Ranjan&#xff0c;Dr. S. Senthamilarasu 出版&#xff1a;Packt 书籍…

GRACE滤波数据处理之DDK系列滤波

以CSR RL06无约束解为例&#xff0c;进行DDK1-8滤波数据处理&#xff0c;人为构造如下有关读取数据的控制文件&#xff1a; Github上下载DDK滤波核函数&#xff1a;GitHub - strawpants/GRACE-filter: Contains software for filtering (destriping) GRACE Stokes coefficients…

Tomact安装配置及使用(超详细)

文章目录 web相关知识概述web简介(了解)软件架构模式(掌握)BS&#xff1a;browser server 浏览器服务器CS&#xff1a;client server 客户端服务器 B/S和C/S通信模式特点(重要)web资源(理解)资源分类 URL请求路径(理解)作用介绍格式浏览器通过url访问服务器的过程 服务器(掌握)…

【Docker】如何注册Hub账号并上传镜像到Hub仓库

一、创建Hub账户 浏览器访问&#xff1a;hub.docker.com 点击【Sign up】注册账号 输入【邮箱】【用户名】【密码】 ps&#xff1a;用户名要有字母数字&#xff1b;订阅不用勾选 点击【Sign up】注册即可 点击【Sign in】登录账号 输入【邮箱】【密码】 点击【Continue】登录 二…

前端工程化Vue使用Node.js永久设置国内高速npm镜像源

前端工程化Vue使用Node.js永久设置国内高速npm镜像源 接续上篇错误收录&#xff0c;此篇通过简单配置永久设置国内高速npm镜像源方法 1.更换新版镜像 清空npm缓存 npm cache clean --force修改回原版镜像源或直接删除配置过的镜像源 npm config set registry https://registr…

SpringDI方式及Redis应用场景的分享

1、为什么Spring和IDEA 都不推荐使用 Autowired 注解 大家在使用IDEA开发的时候有没有注意到过一个提示&#xff0c;在字段上使用Spring的依赖注入注解Autowired后会出现如下警告Field injection is not recommended (字段注入是不被推荐的)&#xff1b;但是使用Resource却不会…

如何用 Redis 实现延迟队列?

延迟队列是一种常见的消息队列模式&#xff0c;用于处理需要延迟执行的任务或消息。Redis 是一种快速、开源的键值对存储数据库&#xff0c;具有高性能、持久性和丰富的数据结构&#xff0c;因此很适合用于实现延迟队列。在这篇文章中&#xff0c;我们将详细讨论如何使用 Redis…

在虚拟环境中找到Qt Designer

Pyqt5中找到Qt Designer 安装Pyqt5和Qt Designer: pip install pyqt5-tools 假设Python的虚拟环境名为:d2l &#xff0c;虚拟环境在d2l文件夹中 D:\Software\d2l\Lib\site-packages\qt5_applications\Qt\bin 双击Qt designer启动 Pyside2中找到Qt Designer 安装pyside2 …