Go 开发规范1

Go 开发规范1

Go 开发规范,包含基本开发规范、多线程、高并发和事务处理,并为每个规范提供正确和错误实例:

一、基本开发规范

1. 命名规范

规范:包名使用小写单字,变量 / 函数采用驼峰命名(导出成员首字母大写),常量使用全大写 + 下划线。

正确示例

复制代码
// 包名:小写单字

package user

// 导出函数:首字母大写

func GetUserByID(id int64) (*User, error) { ... }

// 非导出变量:首字母小写

var maxRetries = 3

// 常量:全大写+下划线

const MAX_CONN = 100

// 接口名:以er结尾

type Reader interface {

  Read() ([]byte, error)

}

错误示例

复制代码
// 错误:包名使用复数和下划线

package users_info

// 错误:导出函数首字母小写

func get_user_by_id(id int64) (*User, error) { ... }

// 错误:常量使用驼峰

const maxConn = 100

// 错误:接口名不以er结尾

type ReadInterface interface { ... }
2. 代码格式

规范 :使用gofmt自动格式化,左括号与关键字同行,每行不超过 80 字符。

正确示例

复制代码
if err != nil {

  return nil, err

}

// 长参数换行

result, err := query(

  ctx,

  "SELECT id, name, email FROM users WHERE age > ?",

  18,

)

错误示例

复制代码
// 错误:左括号另起一行

if err != nil

{

  return nil, err

}

// 错误:超长行未拆分

result, err := query(ctx, "SELECT id, name, email, phone, address, created_at, updated_at FROM users WHERE age > ? AND status = ?", 18, "active")
3. 错误处理

规范 :必须检查错误,使用%w包装错误,禁止忽略错误,业务错误返回error而非panic

正确示例

复制代码
// 正确:检查并包装错误

user, err := getUser(id)

if err != nil {

  return nil, fmt.Errorf("failed to get user: %w", err)

}

// 正确:自定义业务错误

var ErrUserNotFound = errors.New("user not found")

错误示例

复制代码
// 错误:忽略错误

user,_ := getUser(id) // 禁止使用_忽略错误

// 错误:用panic处理业务错误

if user == nil {

  panic("user not found") // 业务错误不应panic

}

// 错误:未包装错误,丢失上下文

user, err := getUser(id)

if err != nil {

  return nil, err // 应添加上下文说明

}
4. 包管理

规范:使用 Go Modules,避免循环依赖,依赖版本使用语义化版本。

正确示例

复制代码
// go.mod 正确示例

module example.com/user-service

go 1.20

require (

  github.com/gin-gonic/gin v1.9.1

  gorm.io/gorm v1.25.3

)

错误示例

复制代码
// 错误:依赖使用master分支

require (

  github.com/gin-gonic/gin master // 应使用具体版本

)

// 错误:存在循环依赖(package A依赖B,B依赖A)

二、多线程(Goroutine)规范

1. Goroutine 管理

规范 :启动 goroutine 必须有退出机制,避免泄露;传递context控制生命周期。

正确示例

复制代码
// 正确:使用context控制退出

func startWorker(ctx context.Context) {

  go func() {

      for {

          select {

          case <-ctx.Done():

              fmt.Println("worker exit")

              return

          case task := <-taskChan:

              process(task)

          }

      }

  }()

}

错误示例

复制代码
// 错误:无退出机制,goroutine泄露

func startWorker() {

  go func() {

      for {

          task := <-taskChan // 当taskChan关闭后会永久阻塞

          process(task)

      }

  }()

}

// 错误:循环中无限制创建goroutine

for_, task := range tasks {

  go process(task) // 任务过多时会耗尽资源

}
2. 同步与通信

规范 :通过channel通信共享数据,而非共享内存;必要时使用sync.Mutex

正确示例

复制代码
// 正确:用channel传递数据

func main() {

  ch := make(chan int)

  go func() {

      ch <- calculate() // 发送结果

  }()

  result := <-ch // 接收结果

}

// 正确:使用Mutex保护共享变量

var count int

var mu sync.Mutex

func increment() {

  mu.Lock()

  defer mu.Unlock()

  count++

}

错误示例

复制代码
// 错误:无同步机制共享变量

var count int

func increment() {

  count++ // 并发修改会导致数据竞争

}

// 错误:过度使用共享内存

var data int

go func() { data = 10 }()

time.Sleep(100ms) // 依赖睡眠同步,不可靠

fmt.Println(data)

三、高并发规范

1. 资源控制

规范 :限制并发数(如使用工作池),避免资源耗尽;使用sync.Pool缓存临时对象。

正确示例

复制代码
// 正确:使用工作池限制并发

func processTasks(tasks []Task) {

  const workerCount = 10

  ch := make(chan Task, len(tasks))

 

  // 填充任务

  for_, t := range tasks {

      ch <- t

  }

  close(ch)

 

  // 启动固定数量的worker

  var wg sync.WaitGroup

  for i := 0; i < workerCount; i++ {

      wg.Add(1)

      go func() {

          defer wg.Done()

          for t := range ch {

              process(t)

          }

      }()

  }

  wg.Wait()

}

// 正确:使用sync.Pool缓存对象

var bufPool = sync.Pool{

  New: func() interface{} {

      return new(bytes.Buffer)

  },

}

func handle() {

  buf := bufPool.Get().(*bytes.Buffer)

  defer bufPool.Put(buf) // 归还

  buf.Reset() // 重置状态

  // 使用buf...

}

错误示例

复制代码
// 错误:无限制并发

func processTasks(tasks []Task) {

  var wg sync.WaitGroup

  for _, t := range tasks {

      wg.Add(1)

      go func(t Task) { // 任务过多时创建大量goroutine

          defer wg.Done()

          process(t)

      }(t)

  }

   wg.Wait()

}

// 错误:频繁创建临时对象

func handle() {

   for i := 0; i < 1000; i++ {

      buf := new(bytes.Buffer) // 高并发下导致大量GC

       // 使用buf...

   }

}
2. 超时控制

规范 :所有 IO 操作(网络、数据库)必须设置超时;使用context.WithTimeout控制。

正确示例

复制代码
// 正确:HTTP请求设置超时

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)

defer cancel()

req, err := http.NewRequestWithContext(ctx, "GET", url, nil)

resp, err := http.DefaultClient.Do(req)

// 正确:数据库查询设置超时

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)

defer cancel()

var user User

err := db.WithContext(ctx).First(&user, id).Error

错误示例

复制代码
// 错误:无超时设置,可能永久阻塞

resp, err := http.Get(url) // 无超时,网络异常时永远等待

// 错误:超时后未释放资源

ctx,_ := context.WithTimeout(context.Background(), 5*time.Second)

req,_ := http.NewRequestWithContext(ctx, "GET", url, nil)

resp,_ := http.DefaultClient.Do(req)

// 未调用cancel(),可能导致资源泄露

四、事务处理规范

1. 事务管理

规范:事务必须有明确的提交 / 回滚逻辑;避免在事务中执行耗时操作。

正确示例

复制代码
// 正确:GORM事务示例

tx := db.Begin()

if tx.Error != nil {

  return err

}

// 操作1

if err := tx.Create(&user).Error; err != nil {

  tx.Rollback() // 出错回滚

  return err

}

// 操作2

if err := tx.Create(&order).Error; err != nil {

   tx.Rollback() // 出错回滚

  return err

}

// 全部成功提交

if err := tx.Commit().Error; err != nil {

  return err

}

错误示例

复制代码
// 错误:未处理事务错误

tx := db.Begin()

tx.Create(&user)

tx.Create(&order)

tx.Commit() // 若中间操作失败,仍会提交部分数据

// 错误:事务中执行耗时操作

tx := db.Begin()

createUser(tx)

time.Sleep(5 * time.Second) // 长时间阻塞事务

createOrder(tx) // 可能导致锁竞争和超时

tx.Commit()
2. 事务隔离

规范:根据业务需求设置合适的隔离级别;避免长事务持有锁。

正确示例

复制代码
// 正确:设置事务隔离级别(MySQL)

tx := db.BeginTx(ctx, &sql.TxOptions{

   Isolation: sql.LevelReadCommitted, // 读已提交

})

// 正确:短事务设计

tx.Begin()

// 仅包含必要的数据库操作

tx.Create(&user)

tx.Create(&order)

tx.Commit() // 快速提交释放锁

错误示例

复制代码
// 错误:使用默认隔离级别(可能不符合业务需求)

tx := db.Begin() // 未指定隔离级别,依赖数据库默认设置

// 错误:长事务持有锁

tx.Begin()

createUser(tx)

sendEmail() // 耗时的外部操作,导致事务长时间未提交

createOrder(tx)

tx.Commit() // 锁持有时间过长,引发并发问题

总结

以上规范覆盖了 Go 开发的核心场景,通过遵循这些规范并参考正确 / 错误实例,可以显著提升代码质量、可维护性和系统稳定性。实际开发中,建议结合静态检查工具(如golintstaticcheck)和 CI 流程强制执行规范。

相关推荐
saberc83 小时前
【vibe coding系列】0行代码编写,使用Go+Vue3+Flutter从0到1开发小绿书(一)
后端·go
_新一10 小时前
Go Slice源码解析
后端·go
小刚子要努力1 天前
基于Koa实现轻量化服务引擎
node.js·代码规范
前端很开门1 天前
程序员的逆天操作,看我如何批量下载iconfont的图标和批量下载 svg 图标
前端·chrome·代码规范
_新一1 天前
Go Context源码学习
后端·go
一碗清汤面1 天前
打造AI代码审查员:使用 Gemini + Git Hooks 自动化 Code Review
前端·git·代码规范
inhere1 天前
gookit/slog v0.6.0 发布:SubLogger支持和上下文增强
后端·go·github
Dream耀1 天前
Promise静态方法解析:从并发控制到竞态处理
前端·javascript·代码规范
程序员爱钓鱼2 天前
Go语言实战案例- Redis实现简单排行榜
后端·google·go