Go | 一分钟掌握Go | 10 - 反射

news2024/9/29 5:24:12

作者:Mars酱

声明:本文章由Mars酱编写,部分内容来源于网络,如有疑问请联系本人。

转载:欢迎转载,转载前先请联系我!

前言

反射你以为只在Java中有吗?Go也有反射机制,很多的标准库中,也使用了反射机制,比如fmt包中的encoding包,都是依赖反射机制的。Go的反射比Java的更简单,就只依赖两两个对象:一个Type,一个Value,前者是得到定义对象的类型,比如定义int类型的变量a,反射之后得到int这个类型;后者是得到该变量的值,如果a没有赋值,那么反射得到的a的值就是0。

怎样反射得到对象的类型?

我们可以通过reflect的TypeOf()函数可以获得任意值的类型Type对象,我们试试:

import (
	"fmt"
	"reflect"
	"testing"
)

// author: mars酱
func Test_reflect2(t *testing.T) {
	var pi float32 = 3.1415926
	reflectType1(pi)
}

func reflectType1(x interface{}) {
    // 调用TypeOf函数
	typeName := reflect.TypeOf(x)
	fmt.Printf("类型为:%s\n", typeName.Name())
}

我创建了一个函数reflectType1,函数内部调用TypeOf得到reflect.Type对象(看下面浮动窗的提示信息)

得到Type对象之后,再调用.Name()函数得到类型的名字,运行一下,得到结果:

我们得到了pi的类型是float32,是不是比java简单多了

怎样反射得到对象的值?

得到了类型对象,那么我们来反射获取一下对象的值。Go中通过反射获取值的方法是通过reflect的ValueOf()函数获取的。我们试试看:

import (
	"fmt"
	"reflect"
	"testing"
)

// author: mars酱
func Test_reflect2(t *testing.T) {
	var pi float32 = 3.1415926
	reflectType1(pi)

	reflectValue1(pi)

}

func reflectType1(x interface{}) {
	typeOf := reflect.TypeOf(x)
	fmt.Printf("类型为:%s\n", typeOf)
}

func reflectValue1(x interface{}) {
	valueOf := reflect.ValueOf(x)
	fmt.Printf("值为:%v\n", valueOf)
}

运行一下,得到结果:

相比java,是不是显得go真的太容易和简单很多啊

怎样反射得到对象结构体?

通常,我们并不是只有基本类型的对象的,我们庞大的业务系统是由很多自定义的结构体对象组成的,这里我们看怎么反射自定的结构体。先自定义一个结构体,然后赋值:

type person struct {
	name string
	age  int
}

man := person{age: 98, name: "mars酱"}

再定义一个函数,用来反射结构体:

func reflectStruct1(x interface{}) {
	// 1. 得到Type
	typeOf := reflect.TypeOf(x)
    // 2. 得到Value
	valueOf := reflect.ValueOf(x)

	// 3. 得到Type下的参数数量
	numField := typeOf.NumField()
	for i := 0; i < numField; i++ {
		// 得到StructField对象
		field := typeOf.Field(i)
		value := valueOf.Field(i)
		fmt.Printf("变量名:%s 索引下标:%d 类型:%v 值:%v \n", field.Name, field.Index, field.Type, value)
	}
}

运行之后,打印结果如下:

这样,就得到了结构体中属性的类型还有值,还得到了属性是下标顺序,name是第一个,下标索引为0,age是第二个,下标索引是1

反射调用函数吧

在java中,我们经常使用反射调用,知道一个对象的类型,去反射得到里面的函数,然后给函数传入参数之后,再调用反射出来的函数,这在java的框架中是家常便饭了,那么这次我们看看Go里面怎么做的。

先定义一个函数,一个简单的函数,我们让这个函数做个加法计算:

func addFunc1(a, b int) int {
	return a + b
}

然后创建一个反射这个函数的函数(稍微有点绕口):

// 反射addFunc1函数的函数
func reflectFunc(x interface{}, a, b int) {
	// 1. 先反射值对象
	funcValue := reflect.ValueOf(x)
	// 2. 传入两个参数给构造函数
	paramList := []reflect.Value{reflect.ValueOf(a), reflect.ValueOf(b)}
	// 3. 反射调用函数
	retList := funcValue.Call(paramList)
	// 4. 获取结果
	fmt.Printf("反射调用得到的结果:%v\n", retList[0].Int())
}

这个反射函数需要传入三个参数:一个x对象,两个需要做加法的变量a和b。最后我们在单元测试函数中去调用:

// 调用反射函数的函数
reflectFunc(addFunc1, 10, 20)

运行一下,得到结果如下:

小结一下

Go的反射相比Java的更简单容易理解,但是有几个点需要知道:

  1. 反射数组、切片、Map、指针等类型的变量,它们调用.Name()函数,得到的都是空;
  2. 反射中的类型如果错误会在真正运行的时候才会引发panic,那很可能是在代码写完的很长时间之后
  3. 使用太多反射的代码会很难阅读和难以理解;
  4. 网传Go的反射的性能低下,而且基于反射实现的代码通常比正常代码运行速度慢一到两个数量级;

所以,斟酌而行。也希望未来Go的性能会更高,毕竟最新版才1.20.*版本呢~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaEE】应用层自定义协议及UDP协议

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶 本篇文章将为大家介绍应用层中UDP协议~~ 在应用层这里&#xff0c;虽然存在一些现有的协议&#xff08;HTTP&#xff09;&#xff0c;但是也有很多情况&#xff0c;需要程序猿自定制协议&a…

OJ 功能介绍 使用手册

目录 服务器配置 OJ界面展示 用户管理 一、批量导入&#xff08;从方便管理角度建议以 学生姓名 作为 用户名 &#xff09; 二、批量生成临时用户 后期修改成需要的用户名和密码 &#xff08;学生登录后修改密码&#xff09; 三、用户自行注册&#xff08;填写邮箱获取验证码…

Nmap入门到高级【第九章】

预计更新Nmap基础知识 1.1 Nmap简介和历史 1.2 Nmap安装和使用方法 1.3 Nmap扫描技术和扫描选项 Nmap扫描技术 2.1 端口扫描技术 2.2 操作系统检测技术 2.3 服务和应用程序检测技术 2.4 漏洞检测技术 Nmap扫描选项 3.1 扫描类型选项 3.2 过滤器选项 3.3 探测选项 3.4 输出选项…

【致敬未来的攻城狮计划】— 连续打卡第二十天:RA2E1_UART —— 串口通信例程

系列文章目录 1.连续打卡第一天&#xff1a;提前对CPK_RA2E1是瑞萨RA系列开发板的初体验&#xff0c;了解一下 2.开发环境的选择和调试&#xff08;从零开始&#xff0c;加油&#xff09; 3.欲速则不达&#xff0c;今天是对RA2E1 基础知识的补充学习。 4.e2 studio 使用教程 5.…

Docker consul服务注册与发现

目录 一、服务注册与发现 1、什么是服务注册与发现 2、什么是consul 3、consul提供的一些关键特性 4、容器更新与发现 二、基于nginx与consul构建自动发现即高可用的Docker服务架构 consul服务器部署 1、建立consul 2、查看集群信息 3、通过http获取集群信息 regist…

SpringBoot+vue文件上传下载预览分片上传

学习链接 Blob & File 上传文件 前台 整个过程&#xff0c;就是在使用FormData 添加 上File&#xff08;这个Blob&#xff09;&#xff0c;并且key要和后台的名字对应上在点击上传按钮开始上传之前&#xff0c;使用了URL.createObjectURL(File)创建blobUrl&#xff0c;…

MySQL数据库之库表管理

一、常用的数据类型&#xff1a; 类型含义tinyint(n)1个字节&#xff0c;范围(-128~127)smallint(n)2个字节&#xff0c;范围(-32768~32767)mediumint(n)3个字节&#xff0c;范围(-8388608~8388607)int(n)4个字节(32个比特位)&#xff0c;整数型&#xff0c;范围(-2147483648~…

JavaEE - 网络编程

一、网络编程基础 为什么需要网络编程&#xff1f; 用户在浏览器中&#xff0c;打开在线视频网站&#xff0c;如优酷看视频&#xff0c;实质是通过网络&#xff0c;获取到网络上的一个视频资源。 与本地打开视频文件类似&#xff0c;只是视频文件这个资源的来源是网络。 相比本…

KALI入门到高级【第五章】

预计更新第一章 入门 1.1 什么是Kali Linux&#xff1f; 1.2 安装Kali Linux 1.3 Kali Linux桌面环境介绍 1.4 基本命令和工具 第二章 信息收集 1.1 网络扫描 1.2 端口扫描 1.3 漏洞扫描 1.4 社交工程学 第三章 攻击和渗透测试 1.1 密码破解 1.2 暴力破解 1.3 漏洞利用 1.4 特…

模糊PID(模糊规则表)

模糊PID的模糊化相关内容,请参看下面的博客文章: PLC模糊控制模糊PID(梯形图实现+算法分析)_RXXW_Dor的博客-CSDN博客博途PLC的模糊PID控制详细内容请查看下面的博客文章:Matlab仿真+博途PLC模糊PID控制完整SCL源代码参考(带模糊和普通PID切换功能)_博途怎么实现模糊pid_…

后端程序员的前端必备【Vue】 - 05 class与style绑定、表单输入绑定、Vue生命周期

class与style绑定、表单输入绑定、Vue生命周期 1 class与style绑定1.1 绑定class1.2 绑定style1.3 练习 2 表单输入绑定3 Vue生命周期3.1 vue生命周期3.2 组件的生命周期钩子 1 class与style绑定 操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是 attri…

【操作系统】操作系统内核

图灵机 当系统中有一个CPU的时候 &#xff0c;MR就是它的状态 当系统中有n个CPU的时候&#xff0c;MR1,MR2…MRn 是它的状态 IRQ和NMI是低电平有效信号 NMI不可屏蔽中断 6502的CPU一共40个引脚 eflags寄存器里的 IF 表示 interrupt enable 1表示可以响应中断&#xff0c;0表示…

破解马赛克有多「容易」?

刷短视频时&#xff0c;估计大家都看过下面这类视频&#xff0c;各家营销号争相曝光「一分钟解码苹果笔刷背后内容」的秘密。换汤不换药&#xff0c;自媒体们戏称其为「破解马赛克」&#xff0c;殊不知让多少不明真相的用户建立起了错误的认知&#xff0c;也让苹果笔刷第 10086…

【网络编程】demo版UDP网络服务器实现

文章目录 一、引入二、服务端实现2.1 创建套接字socket2.2 绑定bind2.3 启动服务器2.4 IP的绑定2.5 读取数据recvfrom 三、用户端实现3.1 绑定问题3.2 发送数据sendto 四、源码 一、引入 在上一章【网络编程】socket套接字中我们讲述了TCP/UDP协议&#xff0c;这一篇就是简单实…

保护移动设备免受恶意软件侵害优秀方法

几天前&#xff0c;移动恶意软件攻击增加了500%显然&#xff0c;我们大多数人都不知道不能很好地保护我们的手机下面小编揭秘有效保护移动设备免受恶意软件侵害的最佳方法。 1、使用移动反恶意软件 恶意软件很容易感染智能手机和平板电脑&#xff0c;因此在设备上安装可靠的…

douyin 之xgorgon0404参数

如果我们想要看抖音的数据&#xff0c;在抓包的时候&#xff0c;会发现有一个xgorgon参数,在请求接口的时候&#xff0c;只需要在请求头携带xgorgon参数&#xff0c;就能获得响应后的数据。 目前抖音的xgorgon0404算法已经还原了&#xff0c; 下面是一个请求的demo。代码如下:…

计算机网络可靠传输的三种基本实现机制

可靠传输的means 在数据链路层会给上层网络层提供可靠传输或者不可靠传输&#xff0c;不可靠传输是指检测到传输差错的时候只是丢弃该分组而不进行任何处理&#xff0c;而可靠传输会给发送者一个信号进行重发该分组。 以下给出的三种基本实现机制是提出一些问题&#xff0c;慢…

截图的背景色如何去除?这里介绍一个小工具

屏幕截图&#xff0c;是方便常用的功能。例如从网页或者视频中截图。但是有时候想去除截图中的背景颜色&#xff0c;怎么办&#xff1f;下面这个案例介绍如何去掉截图中的蓝色背景色。 这个小工具就能帮你方便实现。Web端的便捷小工具链接: http://www.artvily.com/renderCase…

深度学习框架发展趋势

深度学习方法的发展是推动深度学习框架进步的最大动力&#xff0c;因此深度学习框架的功能和设计应顺应 算法和模型的发展趋势&#xff1a; 第一&#xff0c;易用性。深度学习领域仍处于快速发展期&#xff0c;参与者和学习者不断增加&#xff0c;新模型大量提出。因 此&#…

深入篇【C++】类与对象:拷贝构造函数详解

深入篇【C】类与对象&#xff1a;拷贝构造函数详解 ①.拷贝构造函数Ⅰ.概念Ⅱ.特征1.重载形式之一2.参数唯一3.形参必须传引用4.编译器的拷贝函数5.典型调用场景 ②.总结&#xff1a; ①.拷贝构造函数 Ⅰ.概念 在创建对象时&#xff0c;能否创建一个与已存在对象一模一样的新…