[go 反射] 结构体

[go 反射] 结构体

本文你将了解

  1. 不同类型结构体直接通过反射拷贝
  2. 通过反射调用结构体方法
  3. 常踩的坑点

不同类型结构体直接通过反射拷贝

普通的拷贝

type One struct{
    Name string
    Age int
}
var one One=One{"jim",20}
var one_copy One=one//拷贝完成

反射拷贝

type One struct{
    Name string
    Age int
}
type Two struct{
    One string
    Two int
}
type Three struct{
    One string
    Two string
    Three int
    Four bool
}
type str_error string//自制简易错误类型
func (s str_error)Error()string{
    return str_error(s)
}
var one One=One{"jim",20}
var one_copy Two
var one_copyt Three
func main(){
    Struct_Copy_Strict(&one_copy,one)//下文实现的严格拷贝
    Struct_Copy(&one_copy,one)//下文实现带兼容性的拷贝
}
func Struct_Copy[T any](dst *T, src any) (err error) {
    //这里示范为了将代码精简到最简,把很多判断条件都省略了。正常使用,指针判断,类型判断,空值判断都是必不可少的!!!
	dtp, stp := reflect.TypeOf(dst).Elem(), reflect.TypeOf(src)
	dvl, svl := reflect.ValueOf(dst).Elem(), reflect.ValueOf(src)
	var i, j = 0, 0
	var dftp, sftp reflect.Type
	var dfvl reflect.Value
	var setpos []int = make([]int, 0, stp.NumField())
	for i < dtp.NumField() && j < stp.NumField() {//预确定是否能进行拷贝,确保拷贝的完整性,不会拷贝到一半不能拷贝退出,造成dst污染
		dftp, sftp = dtp.Field(i).Type, stp.Field(j).Type
		dfvl = dvl.Field(i)
		if dftp == sftp && dfvl.CanSet() {
			setpos = append(setpos, i)
		}
		i++
	}
	if len(setpos) < stp.NumField() {
		err = str_error("copy struct failed")
		return
	}
	for i = 0; i < len(setpos); i++ {
		dvl.Field(setpos[i]).Set(svl.Field(i))
	}
	return err
}
func Struct_Copy_Strict[T any](dst *T, src any) (err error) {
	dtp, stp := reflect.TypeOf(dst).Elem(), reflect.TypeOf(src)
	dvl, svl := reflect.ValueOf(dst).Elem(), reflect.ValueOf(src)
	if dtp.NumField() == stp.NumField() {
		if dtp.NumField() > 0 {
			for i := 0; i < dtp.NumField(); i++ {
				if dtp.Field(i).Type != stp.Field(i).Type && dvl.Field(i).CanSet() {
					err = str_error("can't copy two struct, because them are different")
					return
				}
			}
			for i := 0; i < dtp.NumField(); i++ {
				dvl.Field(i).Set(svl.Field(i))
			}
		}
	} else {
		err = str_error("can't copy two struct, because them are different")
	}
	return
}

反射调用结构体方法

结构体方法调用反射主要为反射调用函数,如有不清楚请查看 [go 反射] 函数

关键方法

  • NumMethod()reflect.Type接口和reflect.Value都有,查看结构体下方法数量
  • Method(int).Func得到一个reflect.Value类型,使用和正常反射使用函数一样。有一点需注意,参数会多一个指针参数,但是此参数传参时请跳过
import (
    "reflect"
    "fmt"
)
type One struct{
}
func (s One)Greet()string{
    return "hello golang"
}
func (s *One)Greet2()string{
    return "hello golang too"
}

func main(){
    var one One
    tp:=reflect.TypeOf(one)//能识别并调用Greet
    tpp:=reflect.TypeOf(&one)//能识别并调用Greet2
    fmt.Println(tp.NumMethod(),tpp.NumMethod())//1,1
    ans:=tp.Method(0).Func.Call([]reflect.Value{})
    fmt.Println(ans[0].String())
    ans=tpp.Method(0).Func.Call([]refelct.Value{})
}

常踩的坑

  1. 方法首字母大小写问题,首字母小写反射会搜不到方法
  2. 方法传参,自行通过NumIn时得到的结果会比实际需要的参数多一个,所以需要从1号位为起点开始遍历传入参数

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

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

相关文章

深度学习之基于YoloV5的道路地面缺陷检测系统(UI界面)

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、道路地面缺陷检测系统四. 总结 一项目简介 基于YoloV5的道路地面缺陷检测系统利用深度学习中的目标检测算法&#xff0c;特别是YoloV5算法&am…

antd Cascader级联菜单无法赋值回显问题

说起来太丢人了&#xff0c;自己还拿官网例子在这里调试半天&#xff0c;最后发现是一个特别小儿科的问题哈哈 Cascader级联数据是服务端返回然后自己处理过的&#xff0c;使用了cascader的fileNames属性重置字段名&#xff0c;最后发现服务端回传的数据无法赋值回显在组件上&…

vscode设置保存后,自动格式化代码

第一步&#xff1a;打开setting.json文件 第二步&#xff1a;在setting.json中加入以下代码 "editor.formatOnType": true, "editor.formatOnSave": true, "editor.formatOnPaste": true

开发小程序需要多少钱?

随着移动互联网的快速发展&#xff0c;小程序已经成为了企业、个人创业者获取用户、提升品牌影响力的重要工具。然而&#xff0c;对于许多初次接触小程序的人来说&#xff0c;开发小程序需要多少钱&#xff0c;是他们最关心的问题。 首先我们需要明确的是&#xff0c;开发小程…

算法题:870. 优势洗牌

该算法是临时想出来的&#xff0c;Java代码的实现在时间上不占优&#xff0c;之后有时间要优化一下&#xff0c;目前就是给大家提供一下思路。 解题思路&#xff1a;田忌赛马的思想 贪心法。 Step1. 对两个数组进行排序。 Step2. 同时遍历排序后的nums2和nums1&#xff0c;将…

C++初阶(八)类和对象

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、Static成员1、Static概念2、Static特性3、试题 二、友元1、友元的类型2、友元函数3、 友元…

nexus搭建npm私有镜像

假设有一个nexus服务&#xff0c;地址为&#xff1a; http://10.10.33.50:8081/ 创建存储空间 登录后创建存储空间&#xff0c;选择存储类型为File&#xff0c;并设置空间名称为 npm-private 创建仓库类型 2.1 创建hosted类型仓库 创建一个名为 npm-hosted 的本地类型仓库 2.…

毅速丨3D打印在零件修复上潜力巨大

随着科技的飞速发展&#xff0c;3D打印技术逐渐渗透到各个领域&#xff0c;在零件修复方面&#xff0c;3D打印也展现出巨大的潜力和优势。 3D打印技术是一种基于数字模型文件的制造技术&#xff0c;采用逐层堆积材料的方式来制造物体。它具有制造复杂形状零件的能力&#xff0c…

【2024最新】HBuilder X3.1.22【安装】零基础入门到精通,看完这一篇就够了【附安装链接】

软件下载 软件&#xff1a;HBuilder X版本&#xff1a;3.1.22语言&#xff1a;简体中文大小&#xff1a;278.95M安装环境&#xff1a;Win11/Win10/Win8/Win7硬件要求&#xff1a;CPU2.0GHz 内存4G(或更高&#xff09;下载通道①百度网盘丨下载链接&#xff1a;https://pan.bai…

HNU程序设计 练习四-数组(强化)

1.快速公交BRT 【问题描述】 在城市里&#xff0c;快速公交&#xff08;BRT&#xff09;线路为一条直线&#xff0c;在其线路上有 n 个交叉路口&#xff0c;在每个路口都有一个交通信号灯&#xff0c;在红灯与绿灯之间周期性循环。 在绿灯亮起持续 g 秒的期间&#xff0c;允许…

【C++】类和对象(中)之拷贝构造与运算符、操作符重载

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 前言 我们继续学习默认成员函数&#xff0c;本篇文…

线扫相机DALSA-相机平场矫正详细步骤

在相机视野下铺放白色亚克力板或纯白纸&#xff0c;采集图像。打开曲线图。 选择 Line Profile 模式。调节好相应所需的曝光时间、光源、增益和镜头光圈&#xff0c;让白平衡纸显示出来的灰度值大概在 150-200 左右。 在Calibration Algorithm 中将显示的数值设置好。 先暗场…

jbase实现业务脚本化

经过晚上和早上的努力&#xff0c;终于补上框架最后一块了&#xff0c;业务脚本侦听变化后自动编译jar包和调用&#xff0c;实现维护成本低&#xff0c;开发效率高的框架的基本体系。 实现自动编译jar包的类 package appcode;import org.w3c.dom.Document; import org.w3c.do…

无感刷新 token

文章目录 背景基本思路需解决的问题请求进入死循环标记刷新 token 请求避免请求拦截覆盖 refresh token并发刷新 token 完整代码注意&#xff1a;拦截器注册顺序另一种方案&#xff1a;事件驱动刷新 前景提要&#xff1a; ts 简易封装 axios&#xff0c;统一 API 实现在 confi…

海康Visionmaster调试脚本:对脚本进行调试的方法

第一步&#xff0c;在脚本模块中使用导出工程功能&#xff0c;将模块中的代码导出 第二步&#xff0c;找到导出的工程&#xff0c;并打开 第三步&#xff0c;生成解决方案&#xff0c;设置断点&#xff0c;点击 VS 菜单调试中的附加到进程&#xff0c;选择 ShellModuleManage…

计算虚拟化1——CPU虚拟化

目录 vCPU的概念 vCPU和CPU的关系 CPU的Ring级别 CPU虚拟化技术 软件辅助全虚拟化 半虚拟化 硬件辅助虚拟化 计算资源的虚拟化可以分为CPU虚拟化、内存虚拟化、I/O虚拟化三个方面 CPU虚拟化&#xff1a;多个虚拟机共享CPU资源&#xff0c;对虚拟机中的敏感指令进行截获…

EntherNet IP通讯学习

# 哎 最近接触ENIP通讯&#xff0c;但是觉得这玩意真的挺复杂的&#xff0c;主要是资料太少了。 好像大家都在保密一样。 1、学习这个通讯一定是因为实际工作中有用到&#xff0c;所以这个时候你一定有一个PLC做了从站。 OK&#xff0c;那下面继续学习吧&#xff01; 首先先上…

数智赋能!麒麟信安参展全球智慧城市大会

10月31日至11月2日&#xff0c;为期三天的2023全球智慧城市大会长沙在湖南国际会展中心举办&#xff0c;大会已连续举办12届&#xff0c;是目前全球规模最大、专注于城市和社会智慧化发展及转型的主题展会。长沙市委常委、常务副市长彭华松宣布开幕&#xff0c;全球智慧城市大会…

TypeScript 第一站概念篇

前言 &#x1f52e; 好长一段时间没有写文章了&#xff0c;原因是经历了一次工作变动&#xff0c;加入了一个有一定规模的开发团队&#xff0c;前端算上我有四个人&#xff0c;很欣慰&#xff0c;体验一下团队配合的感觉&#xff0c;在我之上有一个组长&#xff0c;比我年长四…

Mozilla Firefox 119 现已可供下载

Mozilla Firefox 119 开源网络浏览器现在可以下载了&#xff0c;是时候先看看它的新功能和改进了。 Firefox 119 改进了 Firefox View 功能&#xff0c;现在可以提供更多内容&#xff0c;如最近关闭的标签页和浏览历史&#xff0c;你可以按日期或网站排序&#xff0c;还支持查…
最新文章