---
name: comment-standards
description: Go 注释规范。编写 Go 代码注释、文档注释时使用。包含包注释、结构体注释、接口注释、函数注释、内联注释的完整规范与示例。
---

# Go 注释规范

**基本原则**：
- **所有注释使用中文**
- **导出符号必须有文档注释**（包、函数、方法、类型、接口、常量、变量）
- **复杂逻辑必须有实现注释**（解释"为什么"，而不是"做了什么"）
- **禁止废话注释**（不要用注释复述代码本身）
- **修改代码时必须同步更新注释**

---

## 包注释

每个包的入口文件（通常是主文件或 `doc.go`）必须有包注释：

```go
// Package account 提供账号管理的业务逻辑服务
// 包含账号创建、修改、删除、权限分配等功能
package account
```

## 结构体注释

所有导出结构体必须有文档注释，说明该结构体代表什么：

```go
// Service 账号业务服务
// 负责账号的 CRUD、角色分配、密码管理等业务逻辑
type Service struct {
    store        *Store
    auditService AuditServiceInterface
}
```

## 接口注释

导出接口必须注释接口用途，每个方法必须说明契约：

```go
// PermissionChecker 权限检查器接口
// 用于查询用户的权限列表
type PermissionChecker interface {
    // CheckPermission 检查用户是否拥有指定权限
    // userID: 用户ID
    // permCode: 权限编码（格式: module:action）
    // platform: 端口类型 (all/web/h5)
    CheckPermission(ctx context.Context, userID uint, permCode string, platform string) (bool, error)
}
```

## 函数和方法注释

**导出函数/方法**必须以函数名开头，说明功能：

```go
// Create 创建账号
// POST /api/admin/accounts
func (h *AccountHandler) Create(c *fiber.Ctx) error {
```

**复杂方法**（超过 30 行或包含复杂业务逻辑）必须额外说明实现思路：

```go
// ActivateByRealname 首次实名激活套餐
// 当用户完成实名认证后，自动激活处于"囤货待实名"状态的套餐：
// 1. 查找该卡所有 status=3（待实名激活）的套餐
// 2. 按创建时间排序，第一个主套餐立即激活（status=1）
// 3. 其余主套餐进入排队状态（status=4）
// 4. 加油包如果绑定了已激活的主套餐则一并激活
func (s *UsageService) ActivateByRealname(ctx context.Context, cardID uint) error {
```

**未导出函数/方法**：
- 简单逻辑（< 15 行）：可以不加注释
- 复杂逻辑（≥ 15 行）或非显而易见的算法：必须加注释

```go
// buildPermissionTree 递归构建权限树
// 采用 map 索引 + 单次遍历算法，时间复杂度 O(n)
func (s *Service) buildPermissionTree(permissions []*model.Permission) []*dto.PermissionTreeNode {
```

## 常量和枚举注释

分组常量必须有组注释，每个值必须有行内注释：

```go
// 用户类型常量
const (
    UserTypeSuperAdmin = 1 // 超级管理员
    UserTypePlatform   = 2 // 平台用户
    UserTypeAgent      = 3 // 代理账号
    UserTypeEnterprise = 4 // 企业账号
)
```

## 内联注释规范

**必须添加内联注释的场景**：

| 场景 | 要求 |
|------|------|
| 复杂条件判断 | 解释判断的业务含义 |
| 多步骤业务流程 | 用编号注释标明每一步 |
| 非显而易见的设计决策 | 解释"为什么这样做"而不是"做了什么" |
| 缓存/事务/并发处理 | 说明策略和原因 |
| 临时方案/兼容逻辑 | 标注 TODO 或说明背景 |

**✅ 好的内联注释（解释为什么）**：

```go
// 使用 Redis 分布式锁防止并发重复创建，锁超时 10 秒
if !s.acquireLock(ctx, lockKey, 10*time.Second) {
    return errors.New(errors.CodeTooManyRequests, "操作过于频繁，请稍后重试")
}

// 先冻结佣金再扣款，保证资金安全（失败时佣金自动解冻）
if err := s.freezeCommission(ctx, tx, orderID); err != nil {
    return err
}
```

**❌ 废话注释（禁止）**：

```go
// 获取用户ID          ← 禁止：代码本身已经很清楚
userID := middleware.GetUserIDFromContext(ctx)

// 创建账号            ← 禁止：变量名已说明意图
account := &model.Account{}

// 返回错误            ← 禁止：return err 不需要注释
return err
```
