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是个非常不错的选择。

相关文章
|
2月前
|
存储 Go C语言
如何用Go开发eBPF程序
【2月更文挑战第7天】
|
2月前
|
开发框架 安全 中间件
Go语言开发小技巧&易错点100例(十二)
Go语言开发小技巧&易错点100例(十二)
31 1
|
9天前
|
前端开发 Java Go
开发语言详解(python、java、Go(Golong)。。。。)
开发语言详解(python、java、Go(Golong)。。。。)
|
1月前
|
JSON Go API
Go语言网络编程:HTTP客户端开发实战
【2月更文挑战第12天】本文将深入探讨使用Go语言开发HTTP客户端的技术细节,包括发送GET和POST请求、处理响应、错误处理、设置请求头、使用Cookie等方面。通过实例演示和代码解析,帮助读者掌握构建高效、可靠的HTTP客户端的关键技术。
|
2月前
|
编译器 Go 持续交付
Go语言模块导入的实践与技巧:提升代码重用与模块化开发效率
【2月更文挑战第9天】在Go语言中,模块导入是实现代码重用和模块化开发的关键环节。本文将介绍Go语言中模块导入的实践与技巧,包括本地模块的导入、远程模块的导入、导入路径的解析与重定向、导入别名与包的重命名等,旨在帮助读者更加高效地进行Go语言的项目开发。
|
2月前
|
自然语言处理 IDE Go
高效Go编程之格式化+代码注释+命名+分号+控制结构
【2月更文挑战第6天】高效Go编程之格式化+代码注释+命名+分号+控制结构
32 0
|
2月前
|
程序员 Go 开发者
Go语言中的跳转控制结构:`goto`、`break` 和 `continue`
【2月更文挑战第3天】在Go语言中,跳转控制结构允许程序员直接控制程序的执行流程,通过`goto`、`break`和`continue`关键字实现代码的跳转、退出循环或跳过循环的某次迭代。本文将深入探讨这些跳转控制结构的使用场景、注意事项以及最佳实践,帮助读者更好地理解和应用Go语言中的跳转控制结构。
|
2月前
|
Go 开发者 索引
Go语言中的循环控制结构解析
【2月更文挑战第3天】本文将详细探讨Go语言中的循环控制结构,包括`for`循环、`range`循环以及`无限循环`的使用方法和适用场景。通过掌握这些循环结构,Go语言开发者能够更加高效地进行迭代操作、处理集合数据以及实现复杂的控制逻辑。
|
2月前
|
Go
Go语言中的条件控制结构详解
【2月更文挑战第3天】本文深入探讨了Go语言中的条件控制结构,包括`if`语句、`switch`语句以及它们的特点、使用场景和最佳实践。通过理解这些结构,读者可以更好地掌握Go语言中的条件判断和流程控制,从而编写出高效、清晰和可维护的代码。
|
2月前
|
Go
Go语言开发小技巧&易错点100例(十一)
Go语言开发小技巧&易错点100例(十一)
16 0