Go业务开发常用关注点

2023-09-21 17:51:30

本文对实际开发场景中面对高频的场景,总结出来的一些处理方案,希望能对业务开发的同学提供帮助!

结构体转换

实际开发中会面对一个相似的数据结构,由于引用不同的包,需要开发转换到对应的结构上,本质上这些数据结构是一致的,但是所在包不同所以不能直接赋值。

常规的方案大致分为下面几种:

  1. 直接转换 struct

这种适合结构完全一致的情况,参数名和类型都必须保持一致;适用场景相对较少,面对不同包的协议转换如果包含一个枚举就无效了

type aType int64
type A struct {
   a aType
}

type bType int64
type B struct {
   a bType
}

func Test(t *testing.T) {
   a := A{a: 1}
   b := B(a)
   fmt.Println(a, b)// 如果把aType和bType直接当做in64就可以正常转换
}

2. 手撸代码

开发手动转换结构,适合字段比较少的结构,同时命名不会很相似,如果相似度较高存在写错的可能,面对复杂有嵌套数据结构效率低下。

3. 正反序列化转换

这种方案相对于第一种具备更强的兼容性,可以通过 tag 来实现不同类型的转换,但是面对不同协议生成的代码还是具有局限性,同时效率比较低下,序列化是比较消耗 cpu 的操作;
需要注意的是,官方的原生 json 库处理大数存在精度丢失的问题,我们这里采用 jsonx 默认支持大数
jsonx: code.byted.org/gopkg/jsonx

type aType int64
type A struct {
   A aType `json:"a"`
}

type bType int64
type B struct {
   A bType `json:"a"`
}

func Test(t *testing.T) {
   aStr := jsonx.ToString(A{1})
   b := &B{}
   _ = jsonx.UnmarshalFromString(aStr, &b)
   fmt.Println(aStr, b)
}

最佳实现

这里的最佳实现其实要区分场景来考虑:

  • 面对高并发或是简单结构的场景,需要减少资源消耗,可以采用【手撸代码】的方式实现
  • 面对并发比较低的场景,通过【正反序列化】是比较好的方案,使用起来更简单

数据库中存储json结构体

表中有extra字段,存储的是扩展信息,比如执行时间,通常的结构声明是这样的:

type BaseInfo struct {
   ID            int64        `json:"id" gorm:"column:id"`
   Extra         string       `json:"extra" gorm:"column:extra"`
}

意味着查询出来结构后还需要进行 unmarshal 操作,且写入数据的时候也要进行 marshal,开发者在修改数据的时候需要额外考虑其他接口所使用的数据结构,用起来不方便。

最佳实践

gorm 是支持很多拓展特性的,通过实现Scan、Value的方法就可以省去在业务代码中序列化的操作,降低开发者的心智负担,优化后大致如下:

type BaseInfo struct {
   ID            int64        `json:"id" gorm:"column:id"`
   Extra *ExtraInfo `json:"check_in_detail" gorm:"column:check_in_detail"`
}

type ExtraInfo struct {
    Info1 `json:"info1"`
}

func (BaseInfo) TableName() string {
   return "base_info"
}

// Value return json value, implement driver.Valuer interface
// 如果接受者是指针,那么就只能是指针来调用
// 如果接受者是值类型,则支持指针、值类型来调用
func (j ExtraInfo) Value() (driver.Value, error) {
   return json.Marshal(j)
}

// Scan scan value into Jsonb, implements sql.Scanner interface
// 接受者要使用指针类型,这才才能实际赋值
func (j *ExtraInfo) Scan(value interface{}) error {
   bytes, ok := value.([]byte)
   if !ok {
      return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", value))
   }
   result := ExtraInfo{}
   var err error
   if len(bytes) > 0 {
      err = json.Unmarshal(bytes, &result)
   }
   *j = result
   return err
}

更多推荐

月木学途开发 6.网址模块

概述效果图数据库设计网站类型表DROPTABLEIFEXISTS`website`;CREATETABLE`website`(`websiteId`int(11)NOTNULLAUTO_INCREMENT,`websiteImg`longtext,`websiteName`varchar(255)DEFAULTNULL

嵌入式Linux驱动开发(I2C专题)(七)

使用GPIO操作I2C设备_IMX6ULL参考资料:Linux文档Linux-5.4\Documentation\devicetree\bindings\i2c\i2c-gpio.yamlLinux-4.9.88\Documentation\devicetree\bindings\i2c\i2c-gpio.txtLin

Selenium-介绍下其他骚操作

ChromeDevTools简介ChromeDevTools是一组直接内置在基于Chromium的浏览器(如Chrome、Opera和MicrosoftEdge)中的工具,用于帮助开发人员调试和研究网站。借助ChromeDevTools,开发人员可以更深入地访问网站,并能够:检查DOM中的元素即时编辑元素和CSS检查和

【Java 基础篇】Java UDP通信详解

UDP(UserDatagramProtocol)是一种无连接的网络传输协议,它不像TCP那样需要建立连接和维护状态,因此更加轻量级。UDP适用于那些对数据传输的实时性要求较高,可以容忍一定数据丢失的场景。本文将详细介绍Java中如何使用UDP协议进行网络通信,包括UDP套接字、数据传输、服务器和客户端的创建等。1.U

云可观测性:提升云环境中应用程序可靠性

随着云计算的兴起和广泛应用,越来越多的企业将其应用程序和服务迁移到云环境中。在这个高度动态的环境中,确保应用程序的可靠性和可管理性成为了一个迫切的需求。云可观测性作为一种解决方案,针对这一需求提供了有效的方法和工具。本文将介绍云可观测性的概念、优势以及它如何提升云环境中应用程序的可靠性和可管理性。一、云可观测性概述掌动

ADB环境搭建和抓取Crash日志实践总结

一、adb下载1.1直接点击下载即可:http://adbshell.com/upload/adb.zip1.2网盘获取链接:https://pan.baidu.com/s/1P9nlRN0RQhPCPDaYg7Cgrg提取码:deng下载到本地解压,双击下图应用程序进行安装,其他文件不用动(与普通应用程序不同,adb

人工智能:ChatGPT与其他同类产品的优缺点对比

引言:自然语言处理技术的快速发展推动了聊天机器人的广泛应用。ChatGPT作为一种强大的语言模型,具有出色的生成能力和上下文理解能力。本文将对比ChatGPT与其他同类产品的优缺点,并展示使用ChatGPT进行对话生成的示例代码。ChatGPT简介ChatGPT是由OpenAI开发的语言模型,基于大规模的预训练数据和深

K8S pod资源、探针

目录一.pod资源限制1.pod资源限制方式2.pod资源限制指定时指定的参数(1)request资源(2)limit资源(3)两种资源匹配方式3.资源限制的示例(1)官网示例2)Pod和容器的资源请求和限制格式(3)CPU资源单位介绍(4)内存资源单位(5)资源限制示例1:(6)资源限制示例2:2.Probe支持三种

模式分类与“组件协作模式”

1.GOF-23模式分类从目的来看:创建型(Creational)模式:将对象的部分创建工作延迟到子类或者其他对象,从而应对需求变化为对象创建时具体类型实现引来的冲击。结构型(Structural)模式:通过类继承或者对象组合获得更灵活的结构,从而应对需求变化为对象的结构带来的冲击。行为型(Behavioral)模式:

Python+Requests+Pytest+YAML+Allure实现接口自动化

本项目实现接口自动化的技术选型:Python+Requests+Pytest+YAML+Allure,主要是针对之前开发的一个接口项目来进行学习,通过Python+Requests来发送和处理HTTP协议的请求接口,使用Pytest作为测试执行器,使用YAML来管理测试数据,使用Allure来生成测试报告一、项目说明本

手动开发-实现SpringMVC底层机制--小试牛刀

文章目录前端控制器Controller注解RequestMapping注解自定义容器LingWebApplicationContext设计handlerList完成分发请求Service注解和AutoWired注解RequestParam注解完整代码在这里说的底层机制的实现主要是指:前端控制器、Controller、S

热文推荐