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

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

之前整理了一篇 Go语言中比较优雅的写法 已经收到了60+点赞,1万+的阅读。

这篇文章作为补充篇,分享一下最近使用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是个非常不错的选择。

最后

感谢阅读,欢迎大家三连:点赞、收藏、投币(关注)!!!

8e95dac1fd0b2b1ff51c08757667c47a.gif

猜你喜欢

转载自juejin.im/post/7102605823003590692
今日推荐