自古以来,反射也是兵家必争之地

这篇具有很好参考价值的文章主要介绍了自古以来,反射也是兵家必争之地。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这几天收到一个战术性需求,将一大坨字段序列化为特定格式的字符串。

大概是下表这样:

序号 字段名 描述 是否必填
0 logVersion 日志版本
1 productName 产品
2 serviceName 服务
...
...
...
25 extend3 扩展字段3
26 extend4 扩展字段3
27 extend5 扩展字段3
checklist-client com.CommonApiController uploadImage 2017-12-27 10:35:08 378 1.0 null null 192.168.35.12 EBJ4945 null null ylKLPAvAsoaWRnqGZhZ6xqZ6hkYxSrVKsQDOSOpwXgAAAA== 0 91 null null 0 202226d4-255f-891c-b627-9efc28ef366b 0 010 -1 null null null null null null

控制点1:必填字段少,若可选字段无值,该字段序列化为“null”;

控制点2:序列化时只显示字段值(有序),字段之间用空格区分。

这不就是自定义序列化 且设置序列化默认值?

真要我挨个字段填充,我眼睛都要对花, 而且很容易漏掉字段。

// 伪代码如下:
  b := bytes.Buffer{}
	b.WriteString("P1")
	b.WriteString(" ")
	b.WriteString("null")
	b.WriteString(" ")
	b.WriteString("null")
	b.WriteString(" ")
	b.WriteString("A")
  ...
  b.WriteString(" ")
  b.WriteString("null")
  log.Info(b.String())

根据"必填字段极少,可选字段默认设为null字符串"的背景,我开始自定义序列化器:

  1. 使用struct来定义结构,便于对必填字段赋值 (这个行为肉眼友好)
  2. 将struct的[字段:字段值]转换为排好序的map键值对
  3. 对排好序的map键值对无脑序列化

将结构体转换为 map, 这个行为涉及元类型的变动,联想到反射。

自古以来,反射也是兵家必争之地, 于是首次操刀golang的反射特性。

思路和伪代码很明确,实操时还是有2点障碍:

  1. golang付map做for循环,键值对的出现是随机的。
  2. 函数传参注意传指针值,而不要传结构体值。

关于第一个问题,利用网上的[提取key放在slice里面,再根据key的排序取map值]的思路是想当然了。
我们的key是字符串,sort.Strings()之后依旧不是自己的预期(预期是按照struct字段出现的先后顺序)。

所以对map做for循环时,能拿到与struct字段出现顺序一致的键值对就是关键。

取巧:

我们利用反射struct时的字段顺序,定义了一个按照struct字段出现顺序为键的map[int]string
这样sort.Ints(keys) 排序之后,for map时依旧是我们预期的键值对顺序。文章来源地址https://www.toymoban.com/news/detail-461377.html

func constructFixedMap(body interface{}) map[int]string {
   
   typ := reflect.TypeOf(body)  //TypeOf返回目标数据类型
   val := reflect.ValueOf(body)  //ValueOf返回目标数据的的值
   if typ.Kind() != reflect.Pointer {
   	fmt.Println("expect pointer")
   	return nil
   }

   typ = typ.Elem() // 返回指针所指向的原值
   val = val.Elem()
   mp := make(map[int]string, 20)
   for i := 0; i < typ.NumField(); i++ { 
   	if typ.Field(i).Type.Kind().String() == "string" {
   		if val.Field(i).String() == "" {    // 可选字段,在反射时被修改
   			mp[i] = "null"
   		} else {
   			mp[i] = val.Field(i).String()     // 必填字段,保持不变
   		}
   	} else {
   		if val.Field(i).CanInt() {
   			mp[i] = strconv.FormatInt(val.Field(i).Int(), 10)
   		} else {
   			mp[i] = "null"
   		}

   	}
   }
   return mp
}

记忆点回顾

  • golang反射在自定义序列化器中的运用。
  • 对map做for循环,键值对的出现是随机的; 对keys排序,根据排序的keys再取map键值对要随机应变。

到了这里,关于自古以来,反射也是兵家必争之地的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ChatGPT必将在文档处理领域大有所为,未来以来,拭目以待【文末送书】

    您好,我是码农飞哥(wei158556),感谢您阅读本文,欢迎一键三连哦 。 💪🏻 1. Python基础专栏,基础知识一网打尽,9.9元买不了吃亏,买不了上当。 Python从入门到精通 😁 2. 毕业设计专栏,毕业季咱们不慌忙,几百款毕业设计等你选。 ❤️ 3. Python爬虫专栏,系统性的学习

    2024年02月02日
    浏览(32)
  • 一直以来,区块链的基础性和底层性,都是人们津津乐道的话题

    一直以来,区块链的基础性和底层性,都是人们津津乐道的话题。正是因为如此,谈及区块链,人们更多地想到的是,它是万能的,它是普适的,它是简单的,它是纯粹的。然而,区块链的这种基础性和底层性,并不仅仅只是体现在它的简单和纯粹上,而是更多地体现在它的

    2023年04月10日
    浏览(35)
  • unity多人联机(Mirror插件)有史以来最全的基础教程(附加报错提示和官方手册修改)

    目录 START👀 (☞゚ヮ゚)☞Mirror简介☜(゚ヮ゚☜) 组件介绍: 组件1:NetworkManager 组件2:NetworkManagerHUD(需要配合Network Manager组件) 组件3:NetworkIdentity 组件4:network discoverynetwork discoveryHUD 错误注意: 最后,对手册内容的一点修改: 今天我们只讲代码和组件,大家拿小本本记好了,字

    2024年02月02日
    浏览(48)
  • 【C语言14】C语言实现顺序表(这可能是CSDN有史以来讲解最详细的顺序表)

    官方定义:顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素

    2024年02月16日
    浏览(41)
  • python实现刮刮乐(遮罩层也是图片)

    python实现刮刮乐(遮罩层也是图片) python实现刮刮乐效果,与普通刮刮乐有些不同,被刮掉的遮罩层是图片,当其被刮掉后,露下面的图片。在游戏循环中,监听鼠标移动事件,来模拟刮开效果。 效果图  Pygame是一组用来开发游戏软件的 Python 程序模块,基于 SDL 库的基础上

    2024年02月06日
    浏览(77)
  • Python 既是解释型语言,也是编译型语言

    哈喽大家好,我是咸鱼 不知道有没有小伙伴跟我一样,刚开始学习 Python 的时候都听说过 Python 是一种解释型语言,因为它在运行的时候会逐行解释并执行,而 C++ 这种是编译型语言 不过我今天看到了一篇文章,作者提出 Python 其实也有编译的过程,解释器会先编译再执行 不

    2024年02月05日
    浏览(45)
  • Python制作爱心跳动代码,你也是天才程序员

    前端时间电视剧《点燃我,温暖你》正在热播中,里面的天才程序员李峋制作的爱心跳动代码是不是震撼了你的心,今天我们用Python来尝试一下制作爱心跳动代码吧! 怎么说呢,用这个表白也可以的,万一她也看这个剧呢,万一就成了呢 哈哈 冲啊,兄弟们 okok 话不多说,现

    2024年02月09日
    浏览(61)
  • 在数据库造数据发现的bug也是bug

           上个月,我和开发小哥讨论过一个问题,开发小哥专门提醒我,页面上新增功能尽可能在前端造一些数据去测试,如果直接从数据库里插入的数据,定位问题还是有些说不清楚。 讨论的过程和细节就是以下的对话内容: 测试小姐姐: 企业设备翻页查询的时候报这个错

    2024年02月02日
    浏览(48)
  • ChatGPT的失败,是认知的失败,也是理解的失败

    当下正在发生的事情,我们早已经历过,而且不止一次。 当下以及可见的未来,ChatGPT除了“比人类更有效地”完成报告和写作等“智能”任务外,更多的恐怕是更多的“想象”了!现在不是一些未知的东西正在做我们不知道的事情,而是一些已知的东西正在做我们知道或不

    2023年04月09日
    浏览(30)
  • 时至今日,Linux会开源,也是一种态度

    什么是开源? 开源通常指开发者公开系统/应用程序源代码。通过对代码进行共享和重用,可以快速开发出高质量、低维护成本的应用程序。这意味着你不再需要花很多时间来学习新技术或编写复杂的代码。 就拿linux来举例子。 Linux系统的发起者 Linus Torvald 奠基了linux kernel的

    2024年02月04日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包