Golang 进阶5—— 反射
Golang 进阶5—— 反射
注意,该文档只适合有编程基础的同学,这里的go教程只给出有区别的知识点
反射:
- 反射可以在运行时动态获取变量的各种信息, 比如变量的类型、 类别等信息。
- 如果是结构体变量,还可以获取结构体本身的信息(结构体的字段、方法)。
- 通过反射, 可以修改变量的值,可以调用关联的方法。
- 使用反射, 需要import(“reflect”)
1.1 main函数
package mainimport ("fmt""reflect"
)// 利用一个函数, 函数的参数定义为空接口
// 空接口没有任何方法,所以可以理解为所有类型都实现了空接口
// 也可以理解为我们可以把任何一种类型赋值给空接口
func testReflect (data interface{}) {// 1、 调用 TypeOf函数, 返回reflect.Type 类型的数据fmt.Println("data type is ", reflect.TypeOf(data))// 2、 调用 ValueOf函数, 返回reflect.Value 类型的数据reVal := reflect.ValueOf(data)fmt.Println("data value is ", reVal)// 3、 如果要获取具体类型的值, 可以调用 Int 方法sum := 100 + reVal.Int()fmt.Println("sum is ", sum)// 4、 reVal 转成空接口i2 := reVal.Interface()fmt.Println("i2 is ", i2)// 5、类型断言n := i2.(int)n2 := n + 200fmt.Println("n2 is ", n2)fmt.Println("i2 type is ", reflect.TypeOf(i2))
}
1.2 输出结果
(base) PS E:\Goproject\src\gocode\testproject03> go run .\main\main.go
data type is int
data value is 10
sum is 110
i2 is 10
n2 is 210
i2 type is int
1.3 结构体情况
import ("fmt""reflect"
)type Student struct {Name stringAge int
}// 利用一个函数, 函数的参数定义为空接口
// 空接口没有任何方法,所以可以理解为所有类型都实现了空接口
// 也可以理解为我们可以把任何一种类型赋值给空接口
func testReflect (data interface{}) {// 1、 调用 TypeOf函数, 返回reflect.Type 类型的数据fmt.Println("data type is ", reflect.TypeOf(data))// 2、 调用 ValueOf函数, 返回reflect.Value 类型的数据reVal := reflect.ValueOf(data)fmt.Println("data value is ", reVal)// 3、 reVal 转成空接口i2 := reVal.Interface()fmt.Println("i2 is ", i2)if s, ok := i2.(Student); ok {fmt.Println("i2 is student:", s.Name)} else {fmt.Println("i2 is not a student")}
}func main () {stu1 := Student{"xiaoxiao", 18}testReflect(stu1)
}
1.4 输出结果
(base) PS E:\Goproject\src\gocode\testproject03> go run .\main\main.go
data type is main.Student
data value is {xiaoxiao 18}
i2 is {xiaoxiao 18}
i2 is student: xiaoxiao
1.5 获取变量类别
import ("fmt""reflect"
)type Student struct {Name stringAge int
}// 利用一个函数, 函数的参数定义为空接口
// 空接口没有任何方法,所以可以理解为所有类型都实现了空接口
// 也可以理解为我们可以把任何一种类型赋值给空接口
func testReflect (data interface{}) {// 1、 调用 TypeOf函数, 返回reflect.Type 类型的数据reType := reflect.TypeOf(data)fmt.Println("data type is ", reType)// 2、 调用 ValueOf函数, 返回reflect.Value 类型的数据reVal := reflect.ValueOf(data)fmt.Println("data value is ", reVal)// 3、 获取变量的类别(大范围)k1 := reVal.Kind()fmt.Println("data kind is ", k1)k2 := reType.Kind()fmt.Println("data kind is ", k2)// 4、 获取变量的类型 (小范围)i2 := reVal.Interface()if n, ok := i2.(Student); ok {fmt.Println("n is ", n)} else {fmt.Println("n is not Student")}}func main () {stu1 := Student{"xiaoxiao", 18}testReflect(stu1)
}
1.6 输出结果
(base) PS E:\Goproject\src\gocode\testproject03> go run .\main\main.go
data type is main.Student
data value is {xiaoxiao 18}
data kind is struct
data kind is struct
n is {xiaoxiao 18}
1.7 对结构体操作
// 1. 定义结构体
type Student struct {Name stringAge int
}// 2. 给结构体绑定方法
func (stu Student) Print() {fmt.Print("调用了Print方法")fmt.Println(stu)
}func (stu Student) GetSum(n1, n2 int) int {return n1 + n2
}func (stu Student) Set(name string, age int) {stu.Name = namestu.Age = age
}func testReflect(data interface{}) {reVal := reflect.ValueOf(data)// 检查 data 是否是指针,并获取指向的值if reVal.Kind() == reflect.Ptr {reVal = reVal.Elem()}fmt.Println(reVal)// 获取结构体中字段的数量n1 := reVal.NumField()fmt.Println("字段的数量:", n1)for i := 0; i < n1; i++ {// 输出字段fmt.Printf("字段 %d 的名字是 %s, 对应的值为 %v \n", i, reVal.Type().Field(i).Name, reVal.Field(i))}// 获取结构体的方法数量n2 := reVal.NumMethod()fmt.Println("方法的数量:", n2)// 输出方法for i := 0; i < n2; i++ {// 输出方法fmt.Printf("方法 %d 的名字是 %s \n", i, reVal.Type().Method(i).Name)}// 调用方法, 调用的方法首字母必须大写reVal.MethodByName("Print").Call(nil)// 调用GetSum方法// 定义Value切片var params []reflect.Valueparams = append(params, reflect.ValueOf(10))params = append(params, reflect.ValueOf(20))sum := reVal.MethodByName("GetSum").Call(params)fmt.Println("sum = ", sum[0])
}func main() {stu := Student{Name: "Tom", Age: 18}testReflect(stu) // 传入 stu 的指针
}
1.8 输出结果
(base) PS E:\Goproject\src\gocode\testproject03> go run .\main\main.go
{Tom 18}
字段的数量: 2
字段 0 的名字是 Name, 对应的值为 Tom
字段 1 的名字是 Age, 对应的值为 18
方法的数量: 3
方法 0 的名字是 GetSum
方法 1 的名字是 Print
方法 2 的名字是 Set
调用了Print方法{Tom 18}
sum = 30
1.9 改值
import ("fmt""reflect"
)// 1. 定义结构体
type Student struct {Name stringAge int
}// 2. 给结构体绑定方法
func (stu Student) Print() {fmt.Print("调用了Print方法")fmt.Println(stu)
}func (stu Student) GetSum(n1, n2 int) int {return n1 + n2
}func (stu Student) Set(name string, age int) {stu.Name = namestu.Age = age
}func testReflect(data interface{}) {reVal := reflect.ValueOf(data)// 通过setInt方法修改值n := reVal.Elem().NumField()fmt.Println("结构体中字段个数为:", n)reVal.Elem().Field(0).SetString("Jack")reVal.Elem().Field(1).SetInt(30)
}func main() {stu := Student{Name: "Tom", Age: 18}testReflect(&stu) // 传入 stu 的指针fmt.Println(stu)
}
1.10 输出结果
(base) PS E:\Goproject\src\gocode\testproject03> go run .\main\main.go
结构体中字段个数为: 2
{Jack 30}
相关文章:
Golang 进阶5—— 反射
Golang 进阶5—— 反射 注意,该文档只适合有编程基础的同学,这里的go教程只给出有区别的知识点 反射: 反射可以在运行时动态获取变量的各种信息, 比如变量的类型、 类别等信息。如果是结构体变量,还可以获取结构体本…...
react 封装防抖
封装防抖 import React, { useRef, useEffect, useCallback } from react;function useDebounce(fn, delay) {const delayRef useRef(delay);const fnRef useRef(fn);// 更新ref值useEffect(() > {delayRef.current delay;}, [delay]);useEffect(() > {fnRef.current…...
Java项目-----图形验证码登陆实现
原理: 验证码在前端显示,但是是在后端生成, 将生成的验证码存入redis,待登录时,前端提交验证码,与后端生成的验证码比较. 详细解释: 图形验证码的原理(如下图代码).前端发起获取验证码的请求后, 1 后端接收请求,生成一个键key(随机的键) 然后生成一个验证码作为map的valu…...
【网络代理模块】反向代理(上)
1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求,然后将请求转发给内部网络上的服务器,将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说,反向代理就相当…...
2-112基于matlab的协同干扰功率分配模型
基于matlab的协同干扰功率分配模型,带操作界面的功率分配GUI,可以实现对已有功率的分配优化,可以手动输入参数值。4个干扰山区分二批总干扰功率,每个扇区包括威胁总系数、综合压制概率、目标函数增量等。程序已调通,可…...
数据结构之——二叉树
一、二叉树的基本概念 二叉树是数据结构中的重要概念,每个节点最多有两个子树,分别为左子树和右子树。这种结构具有明确的层次性和特定的性质。 二叉树有五种基本形态: 空二叉树:没有任何节点。只有一个根结点的二叉树ÿ…...
多层感知机(MLP)实现考勤预测二分类任务(sklearn)
1、基础应用: https://blog.csdn.net/qq_36158230/article/details/118670801 多层感知机(MLP)实现考勤预测二分类任务(sklearn) 2、分类器参数:https://scikit-learn.org/dev/modules/generated/sklearn.neural_network.MLPClassifier.html 3、损失函数…...
文件与目录的基本操作
前提:使用su root 切换到权限最大的root用户 1.显示当前工作目录的绝对路径(pwd) 用途:用于显示当前工作目录的绝对路径的命令。无论用户在文件系统的哪个位置,pwd 命令都能提供当前所在位置的完整路径信息。 用法&a…...
Python入门笔记(三)
文章目录 第八章 字典dict8.1 创建字典:{}、dict()、字典生成式、zip()8.2 获取键对应的值:get()8.3 in, not in判断键是否在字典中8.4 增加键值对:fromkeys()、setdefault()、update()8.5 删除键值对:del语句、clear(…...
PostgreSQL 任意命令执行漏洞(CVE-2019-9193)
记一次授权攻击通过PostgreSql弱口令拿到服务器权限的事件。 使用靶机复现攻击过程。 过程 在信息收集过程中,获取到在公网服务器上开启了5432端口,尝试进行暴破,获取到数据库名为默认postgres,密码为1 随后连接进PostgreSql …...
使用tgz包下载安装clickhouse低版本
1.下载安装包 官方下载地址:https://packages.clickhouse.com/tgz/stable 阿里云下载地址:clickhouse-tgz-stable安装包下载_开源镜像站-阿里云 共需要下载四个文件 clickhouse-common-static-20.3.10.75.tgz clickhouse-common-static-dbg-20.3.10.7…...
外包功能测试干了6个月,技术退步太明显了。。。。。
先说一下自己的情况,本科生,23年通过校招进入武汉某软件公司,干了差不多6个月的功能测试,今年中秋,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我就在一个外包企业干了6个月的功…...
动态规划和贪心算法
目录 动态规划和贪心算法 动态规划 贪心算法 两者之间的区别 动态规划和贪心算法 是两种经典的算法设计策略,它们各自具有独特的特点和适用场景。 动态规划 动态规划是一种将复杂问题分解为更简单子问题的求解方法。它特别适用于那些具有重叠子问题和最优子结构特性的问…...
python爬虫--tx动漫完整信息抓取
python爬虫--tx动漫完整信息抓取 一、采集主页信息二、采集详情页信息三、完整代码一、采集主页信息 先看一下采集到的信息,结果保存为csv文件: 打开开发者工具,找到数据接口。 使用xpath提取详情页url。 二、采集详情页信息 如上图所示,使用xpath提取详情页的标题、作…...
《使用Java做爬虫和使用python做爬虫哪个好》
使用Java做爬虫和使用python做爬虫哪个好 Java 和 Python 都是非常出色的编程语言,在爬虫领域各有其优势,具体使用哪种语言更好取决于多种因素: 一、开发效率 1. Python Python 以其简洁、易读的语法而闻名。在爬虫开发中,有许…...
如果我想开发一个APP,需要准备哪些材料呢
开发一个APP需要准备的材料相对复杂,涵盖了公司资质、技术资源、支付接口以及第三方服务等多个方面。以下是一份详细的材料清单: 一、公司资质证明 营业执照:需要提供公司的营业执照副本,用于申请企业支付、域名备案、APP上架及…...
告别论文初稿焦虑!ChatGPT让你轻松完成写作!
AIPaperGPT,论文写作神器~ https://www.aipapergpt.com/ 在面对繁琐的论文写作时,很多人都会遇到无从下手的困惑,尤其是论文初稿阶段,往往需要大量的时间来组织思路和编写内容。然而,随着AI技术的发展,像…...
mongodb 数据迁移,亲测成功!
mysql进行数据迁移,最简单的不过是导出sql,然后在运行sql,数据也自然迁移过去了。 可是mongodb里,我们存储的是文件,是怎么做到的呢,当我在翻阅网上博客的时候,并没有发现有这方面的顾虑。 当…...
如何使用ssm实现疫情居家办公OA系统
TOC 10902ssm疫情居家办公OA系统 系统概述 进过系统的分析后,就开始记性系统的设计,系统设计包含总体设计和详细设计。总体设计只是一个大体的设计,经过了总体设计,我们能够划分出系统的一些东西,例如文件、文档、数…...
深入了解 MySQL 中的 JSON_CONTAINS
深入了解 MySQL 中的 JSON_CONTAINS MySQL 5.7 及更高版本引入了对 JSON 数据类型的支持,使得在数据库中存储和查询 JSON 数据成为可能。在这些新功能中,JSON_CONTAINS 函数是一个非常有用的工具,允许我们检查一个 JSON 文档是否包含特定的值…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
前端调试HTTP状态码
1xx(信息类状态码) 这类状态码表示临时响应,需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分,客户端应继续发送剩余部分。 2xx(成功类状态码) 表示请求已成功被服务器接收、理解并处…...
高分辨率图像合成归一化流扩展
大家读完觉得有帮助记得关注和点赞!!! 1 摘要 我们提出了STARFlow,一种基于归一化流的可扩展生成模型,它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流(TARFlow&am…...
