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 = 100
	reflectTest01(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 string
	Age  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 := 10
	iValue := reflect.ValueOf(&i)
	// 获取指针进行修改值
	iValue.Elem().SetInt(20)
	fmt.Println(i)
}

练习

func TestReflect(t *testing.T) {
	var v float64 = 1.2
	value := 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.Value
	params = append(params, reflect.ValueOf(10))
	params = append(params, reflect.ValueOf(40))
	res := mValue.Method(0).Call(params)
	fmt.Println("res ", res[0].Int())
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【学习笔记二十九】EWM较特殊的业务场景

一、供应商寄售业务相关 1.创建寄售物料、寄售信息记录以及寄售的采购订单 2.创建交货单 3.维护入库交货 行项目里存在C寄售的标识 4.创建上架的仓库任务并确定 查看仓位库存&#xff0c;发现仓位库存里存在寄售标识C以及寄售库存所有方 5.寄售转自有 ①首先MIGO里进行寄…

Linux 权限与软件包管理器 yum

一. 研究Linux默认权限 目录 &#xff0c;起始权限&#xff1a;777 普通文件&#xff0c;起始权限666 Linux系统中存在权限掩码 使用umask指令也可以改变掩码 如果将掩码改为0000 我们可以看到权限发生改变&#xff08;重新设置掩码&#xff09; 最终权限起始权限 去掉 权限…

0426_C高级4

练习1&#xff1a; 输入一个数字&#xff0c;实现数字逆置&#xff08;不使用字符串截取方式&#xff09; 1 #!/bin/bash2 read -p "输入一个数字&#xff1a;" number3 p$number4 result5 while [ $p -ne 0 ]6 do7 result$((result*10p%10))8 p$((p/10))9 …

Python基础10-使用正则表达式进行文本处理

在编程过程中&#xff0c;我们经常需要对文本进行处理&#xff0c;以提取、替换或分割特定的字符串。正则表达式&#xff08;Regular Expression&#xff09;是一种强大的文本处理工具&#xff0c;它可以帮助我们实现这些任务。以下是使用正则表达式进行文本处理的一些基本方法…

react-lib 读取本地模板创建PDF

读取本地文件和读取远程的一样&#xff0c;都使用fetch去获取 async function modifyPdf() {let url ./template.pdflet existingPdfBytes await fetch(url).then(res > res.arrayBuffer()) // 这里也有问题要转一下const d new Uint8Array(existingPdfBytes)const pdfDo…

Mysql索引规范及原理分析

1 Mysql存储引擎 MySQL中的数据用各种不同的技术存储在文件中&#xff0c;每一种技术都使用不同的存储机制、索引技巧、锁定水平并最终提供不同的功能和能力&#xff0c;这些不同的技术以及配套的功能在MySQL中称为存储引擎。 存储引擎是MySQL将数据存储在文件系统中的存储方…

235 基于matlab的时频盲源分离(TFBSS)算法

基于matlab的时频盲源分离&#xff08;TFBSS&#xff09;算法&#xff0c;TFBSS用空间频率分布来分离非平稳信号&#xff0c;可以分离具有不同时频分布的源信号&#xff0c;也能够分离具有相同谱密度但时频分布不同的高斯源。同时&#xff0c;该算法在时频域上局域化源信号能量…

39岁TVB靓仔小生自曝恋情,曾沦为洗车工如今半年赚足7位数

39岁高钧贤自从2005年参加香港先生选举夺冠后&#xff0c;之后加入TVB拍摄过多套电视剧集&#xff0c;最近更有份参与《逆天奇案2》&#xff0c;日前他回到TVB电视城一厂与冯盈盈宣传剧集&#xff0c;更随即拍摄短片纪录放在网上分享&#xff0c;意外曝光TVB餐厅餐单&#xff0…

如何使用IDEA直接连接MySQL数据库

如何使用IDEA直接连接MySQL数据库 新建一个空项目打开DataBase窗口连接数据库第一次连接 需要先下载驱动上一步驱动下载太慢怎么办&#xff1f;下载好驱动后 测试连接 新建一个空项目 打开DataBase窗口 连接数据库 第一次连接 需要先下载驱动 如果这里下载的很慢 看下一步解决…

DaVinci Fusion Studio 19 for Mac/win:影视后期特效合成的巅峰之作

在影视后期制作的广袤天地里&#xff0c;一款强大的特效合成软件如同一位技艺高超的魔法师&#xff0c;能够化腐朽为神奇&#xff0c;将普通的影像素材转变为震撼人心的视觉盛宴。而DaVinci Fusion Studio 19&#xff0c;正是这样一款备受影视从业者推崇的巅峰之作。 无论是Ma…

矩阵按列相乘运算的并行化实现方法

这两天一直在琢磨如下矩阵计算问题。 已知dm矩阵X和hq矩阵Y&#xff0c;求如下矩阵&#xff1a; 其中X(:,i), Y(:,j)分别表示矩阵X, Y的第i列和第j列&#xff0c;易知Z为dh矩阵。 如果直接串行计算矩阵Z&#xff0c;两个循环共有mq&#xff0c;则会很慢&#xff0c;能不能并行化…

【b站李同学的Lee】Part 3 服务器开发 NodeJS+Gulp基础入门+实战

课程地址&#xff1a;【NodeJSGulp基础入门实战】 https://www.bilibili.com/video/BV1aE411n737/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 9 服务器端基础概念 9.1 网站的组成 9.2 Node网站服务器 9.3 IP地址 9.4 域名 9.5 端口 9…

SCSS全局配置 vue项目(二)

目录 1、先要查看node版本 2、安装对应的node-sass、sass-loader版本 2.1根据项目使用的node版本安装对应的node-sass版本 2.2根据node-sass版本选择兼容的sass-loader版本&#xff0c;不然项目无法正常运行 3、在 vue.config.js 中配置&#xff1a; 4、在组件中…

刷题训练之前缀和

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;熟练掌握前缀和算法。 > 毒鸡汤&#xff1a;学习&#xff0c;学习&#xff0c;再学习 ! 学&#xff0c;然后知不足。 > 专栏选自&#xff1a;刷题…

物联网的基本功能及五大核心技术——青创智通

工业物联网解决方案-工业IOT-青创智通 物联网基本功能 物联网的最基本功能特征是提供“无处不在的连接和在线服务”&#xff0c;其具备十大基本功能。 &#xff08;1&#xff09;在线监测&#xff1a;这是物联网最基本的功能&#xff0c;物联网业务一般以集中监测为主、控制为…

Vitis HLS 学习笔记--C/C++ static 关键字的作用

目录 1. 简介 2. c/c共有性质 3. c独有性质 4. 示例说明 5. static 对于 HLS 工具的影响 6. 总结 1. 简介 在Vitis HLS中&#xff0c;偶尔会用到 static 关键字。考虑到Vitis HLS同时兼容C和C语言&#xff0c;有必要理解这两种语言中static关键字细微差异。本文旨在梳理…

Centos7.9系统MySQL5.7.32升级为5.7.44(生成环境操作)

1.背景 由于客户进行等保漏扫和渗透&#xff0c;生成环境mysql数据库被扫描出了 高危漏洞。 如图&#xff1a;部分漏洞 查看漏洞详细信息&#xff0c;建议升级到指定版本解决&#xff1a; 说明&#xff1a; 本文仅适合使用当前数据库为 RPM 安装方式 2.升级前准备 查看环…

串口服务器可以直接连接工业路由器吗

串口服务器可以直接连接工业路由器吗 在工业物联网的架构中&#xff0c;串口服务器和工业路由器都是不可或缺的重要组件。串口服务器的主要功能是将串口通信转换为网络通信&#xff0c;实现数据的远程传输和管理&#xff1b;而工业路由器则负责在工业环境中提供稳定、可靠的网…

QT入门:计算圆面积的QT开始以及日历相关

QT入门&#xff1a;计算圆面积的QT开始以及日历相关 使用的工具为Qt creator 如图所示的为Qt的一个基本目录&#xff0c;首先打开mainwindow.ui进行设计&#xff0c;首先是讲解日历的&#xff0c;可以完全不用写代码&#xff0c;只在mainwindow.ui即可实现。 这是最后的一个成…

YES-2000B数显压力试验机技术方案书

一、简介 本机采用主机与液压系统集于一体的结构形式&#xff0c;结构紧凑&#xff0c;小巧玲珑。采用液压加荷、电子测力&#xff0c;具有加荷数率显示&#xff0c;峰值保持等功能&#xff0c;并配有微型打印机。 外观示意图 二、 液压系统 油箱内的液压油通过电机带动高压…