Go开发技巧和踩坑分享 | 代码结构 调试技巧 配置文件 元数据

简介: 分享一下最近使用GoFrame开发go项目的经验分享。

统一代码结构顺序


在同一文件中,如果存在类型(结构体)、常量、变量、方法(公共/私有)定义的时候,最好按照以下顺序组织代码结构,以方便维护:


  1. 类型定义(结构体定义)
  2. 常量定义
  3. 变量定义
  4. 方法定义(公共)
  5. 方法定义(私有)


例如:


// 类型定义
type Xxx struct {}
// 常量定义
const (
    internalConstName = "xxx"
)
// 变量定义
var (
    internalVariable = "xxx"
)
// 方法定义(公开)
func GetXxx() {
}
// 方法定义(私有)
func doGetXxx() {
}


不要问我为什么?在团队开发中一定要有统一的规范,方便大家更好的理解代码,降低理解成本。


配置文件的管理


goframe建议大家使用配置文件,以便区分不同的运行环境连接不同的DB、CACHE、NSQ、三方的AKSK等配置信息。

这些配置文件一定是要加到gitignore中的,避免导致运行环境的混乱。

当我们有修改配置文件时,一定要记得同步修改多个环境的配置文件,避免导致未知问题。

当排查业务逻辑拍查不到原因时,想想是不是忘记修改了配置文件,这虽然是个低级错误,但确实坑了不少人。


尤其当遇到了本地环境运行正常,但是测试环境或者生产环境运行异常,且代码完全一致。首先排查机器是否正常,机器运行状态没问题后马上排查一下是不是配置文件不一致。


调试技巧


我习惯在项目中搞一个test文件,进行功能测试。


绑定cmd


首先,在main.go中绑定gcmd,允许通过cmd运行test文件


package main
import (
   "github.com/gogf/gf/os/gcmd"
   "myApp/app/test"
)
func main() {
    .
    .
    .
   _ = gcmd.BindHandle("test", test.Run) //调试脚本统一写在这里 避免混淆
   _ = gcmd.AutoRun()
}


test文件


package test
func Run() {
   testDemo()
}
func testDemo() {
   //这是结构体
   var req *notify.NotifyServer 
   //这是json
   jsonInput := `{"msg_type":x,"source":x,"msg_send_time":x,"msg_data":{"xx":"xxxxxxx"}}`
   //把json转成结构体
   err := gconv.Struct(jsonInput, &req)
   if err != nil {
      logs.Info("test", "转换错误:%v", err)
   }
   g.Dump("req:", req)
   _ = f.StatusComfirm(context.Background(), req)
}


运行cmd


通过下述命令启动测试文件


go run main.go test


这样做的好处至少有2点:


  1. 不需要借助postman或者apipost就能调试自己的项目
  2. 当然我们也可以直接写到脚本文件中,但是那样做可能会和正常的脚本逻辑混淆。我们把需要进行测试的功能写到test中,能够避免歧义,降低团队的理解成本。


元数据 gmeta


作用:


主要用于嵌入到用户自定义的结构体中,比如声明对应的数据库

通过标签的形式给gmeta包的结构体打上自定义的标签内容,在运行时可通过Data/Get方法获取这些自定义的标签内容


package main
import (
   "fmt"
   "github.com/gogf/gf/util/gmeta"
)
func main() {
   type User struct {
      gmeta.Meta `orm:"user" db:"mysql"`
      Id         int
      Name       string
   }
   //通过Data获得结构体中的gmeta元数据标签,返回map类型
   fmt.Println(gmeta.Data(User{})) //map[db:mysql orm:user]
   //获得gmeta元数据标签的特定值
   fmt.Println("orm:", gmeta.Get(User{}, "orm")) //orm: user
}


打印结果


map[db:mysql orm:user]
orm: user


在项目中如果有类似需求,那么gmeta是个非常不错的选择。

相关文章
|
3月前
|
缓存 弹性计算 API
用 Go 快速开发一个 RESTful API 服务
用 Go 快速开发一个 RESTful API 服务
|
3月前
|
JSON 运维 Go
Go 项目配置文件的定义和读取
Go 项目配置文件的定义和读取
|
1天前
|
Java 程序员 Go
Go语言的开发
【10月更文挑战第25天】Go语言的开发
9 3
|
2月前
|
关系型数据库 MySQL Go
go抽取mysql配置到yaml配置文件
go抽取mysql配置到yaml配置文件
|
18天前
|
JSON 搜索推荐 Go
ZincSearch搜索引擎中文文档及在Go语言中代码实现
ZincSearch官网及开发文档均为英文,对非英语用户不够友好。GoFly全栈开发社区将官方文档翻译成中文,并增加实战经验和代码,便于新手使用。本文档涵盖ZincSearch在Go语言中的实现,包括封装工具库、操作接口、统一组件调用及业务代码示例。官方文档https://zincsearch-docs.zinc.dev;中文文档https://doc.goflys.cn/docview?id=41。
|
3月前
|
缓存 NoSQL 数据库
go-zero微服务实战系列(五、缓存代码怎么写)
go-zero微服务实战系列(五、缓存代码怎么写)
|
3月前
|
Java 数据库连接 数据库
携手前行:在Java世界中深入挖掘Hibernate与JPA的协同效应
【8月更文挑战第31天】Java持久化API(JPA)是一种Java规范,为数据库数据持久化提供对象关系映射(ORM)方法。JPA定义了实体类与数据库表的映射及数据查询和事务控制方式,确保不同实现间的兼容性。Hibernate是JPA规范的一种实现,提供了二级缓存、延迟加载等丰富特性,提升应用性能和可维护性。通过结合JPA和Hibernate,开发者能编写符合规范且具有高度可移植性的代码,并利用Hibernate的额外功能优化数据持久化操作。
38 0
|
3月前
|
Go C语言
Go语言:新时代的编程英雄,让你的代码驾驭未来!
【8月更文挑战第29天】Go,或称Golang,是由谷歌开发的一种静态强类型的编译语言,旨在融合C语言的高效性和高级语言的易用性。它简洁、优雅,广泛应用于高性能服务器和网络应用开发。本文将通过环境搭建、Hello World示例、变量、常量、控制结构、函数、结构体、接口及错误处理等示例,带你快速入门Go语言,领略其简洁高效的魅力,激发你的编程热情。
39 0
|
3月前
|
消息中间件 缓存 API
go-zero微服务实战系列(三、API定义和表结构设计)
go-zero微服务实战系列(三、API定义和表结构设计)
|
3月前
|
JSON 编解码 中间件
go-zero代码生成器助你高效开发
go-zero代码生成器助你高效开发