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

相关推荐
深圳老胡9 小时前
STM32CubeMX 生成 CMake 工程,用 VSCode 编译与调试的完整流程
笔记·stm32·单片机·代码规范
newerp10 小时前
Execution Trace 深入实战:可视化调度与系统停顿分析
后端·程序员·go
newerp14 小时前
Go 性能分析工具 pprof:CPU、Heap 与 Goroutine 实战
后端·程序员·go
用户1257585243615 小时前
Golang后台管理框架推荐:完整后台、Admin Panel、CRUD生成器如何选?
go
星星泡饭吃15 小时前
【信息安全】越权防护设计评审指南
代码规范
GlobalSign数字证书17 小时前
申请 EV 代码签名证书需要准备哪些材料?
代码规范
深圳老胡17 小时前
STM32F4 OTA 升级双 App 方案设计与实现
笔记·stm32·单片机·代码规范
皓月盈江17 小时前
Go读写TXT文件
开发语言·后端·golang·go·读写txt文件·bufio·go读写txt
除不掉的灰色18 小时前
Go 语言快速理解
go
深圳老胡19 小时前
STM32F4 OTA升级:单App与双App方案优缺点对比
笔记·stm32·单片机·代码规范