Skip to content

文档注释规范

核心原则

代码注释必须清晰准确,使用标准格式,确保导出内容有文档说明。

允许的做法

Go 后端注释

包注释

在 package 语句前添加包注释

go
// ✅ 正确 - 包注释
// Package handler implements HTTP request handlers.
package handler

// Package service contains business logic implementations.
package service

// Package utils provides common utility functions.
package utils

函数注释

导出的函数必须添加注释,注释以函数名开头

go
// ✅ 正确 - 函数注释
// NewService creates a new Service instance with the given dependencies.
func NewService(db *gorm.DB, config *Config) *Service {
    return &Service{db: db, config: config}
}

// Create creates a new record in the database.
// Returns the created record and error if any.
func (s *Service) Create(ctx context.Context, req *CreateRequest) (*Model, error) {
    // 参数验证
    if req.Name == "" {
        return nil, errors.New("参数不完整")
    }

    // 创建记录
    model := &Model{
        Name:      req.Name,
        CreatedAt: time.Now().Unix(),
    }

    if err := s.db.WithContext(ctx).Create(model).Error; err != nil {
        return nil, fmt.Errorf("创建失败: %w", err)
    }

    return model, nil
}

结构体注释

导出的结构体必须添加注释

go
// ✅ 正确 - 结构体注释
// Model represents a data model in the system.
type Model struct {
    ID        int64  `json:"id" gorm:"column:id"`
    Name      string `json:"name" gorm:"column:name"`
    Status    string `json:"status" gorm:"column:status"`
    CreatedAt int64  `json:"created_at" gorm:"column:created_at"`
}

// CreateRequest contains fields for creating a new record.
type CreateRequest struct {
    Name   string `json:"name" validate:"required"`
    Status string `json:"status" validate:"required"`
}

// Response represents the API response structure.
type Response struct {
    Success bool        `json:"success"`
    Data    interface{} `json:"data,omitempty"`
}

接口注释

go
// ✅ 正确 - 接口注释
// Repository defines methods for data access.
type Repository interface {
    // Create creates a new record.
    Create(ctx context.Context, model *Model) error

    // GetByID retrieves a record by its ID.
    GetByID(ctx context.Context, id int64) (*Model, error)

    // Delete removes a record by its ID.
    Delete(ctx context.Context, id int64) error
}

复杂逻辑注释

go
// ✅ 正确 - 复杂逻辑添加实现注释
func (s *Service) Process(ctx context.Context, data *Data) error {
    // 1. 验证数据完整性
    if err := s.validate(data); err != nil {
        return err
    }

    // 2. 开始事务处理
    return s.db.Transaction(func(tx *gorm.DB) error {
        // 2.1 创建主记录
        if err := tx.Create(data).Error; err != nil {
            return fmt.Errorf("创建主记录失败: %w", err)
        }

        // 2.2 创建关联记录
        for _, item := range data.Items {
            if err := tx.Create(item).Error; err != nil {
                return fmt.Errorf("创建关联记录失败: %w", err)
            }
        }

        return nil
    })
}

TypeScript 前端注释

接口注释

使用 JSDoc 注释描述接口和类型

typescript
// ✅ 正确 - 接口注释
/**
 * 数据模型
 */
interface Model {
  /** 记录 ID */
  id: number;
  /** 名称 */
  name: string;
  /** 状态 */
  status: 'active' | 'inactive';
  /** 创建时间 */
  createdAt: number;
}

/**
 * 创建请求参数
 */
interface CreateRequest {
  /** 名称(必填) */
  name: string;
  /** 状态(必填) */
  status: string;
}

组件 Props 注释

typescript
// ✅ 正确 - Props 注释
interface ComponentProps {
  /**
   * 标题
   */
  title: string;

  /**
   * 数据列表
   */
  dataSource: Model[];

  /**
   * 是否加载中
   * @default false
   */
  loading?: boolean;

  /**
   * 编辑回调
   */
  onEdit?: (id: number) => void;

  /**
   * 删除回调
   */
  onDelete?: (id: number) => void;
}

function Component({ title, dataSource, loading = false }: ComponentProps) {
  return <div>{/* ... */}</div>;
}

函数注释

typescript
// ✅ 正确 - 函数注释
/**
 * 验证邮箱格式
 * @param email - 邮箱地址
 * @returns 是否有效
 */
function validateEmail(email: string): boolean {
  const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return regex.test(email);
}

/**
 * 格式化时间戳
 * @param timestamp - Unix 时间戳(秒)
 * @param format - 格式化字符串
 * @returns 格式化后的时间字符串
 */
function formatTimestamp(timestamp: number, format: string = 'YYYY-MM-DD'): string {
  return dayjs.unix(timestamp).format(format);
}

自定义 Hooks 注释

typescript
// ✅ 正确 - Hooks 注释
/**
 * 数据列表 Hook
 * @param filters - 筛选条件
 * @returns 数据列表、加载状态和刷新函数
 */
function useDataList(filters: Filters) {
  const [loading, setLoading] = useState(false);
  const [dataSource, setDataSource] = useState<Model[]>([]);

  const loadData = async () => {
    setLoading(true);
    const { data } = await service.getList(filters);
    setDataSource(data || []);
    setLoading(false);
  };

  useEffect(() => {
    loadData();
  }, [filters]);

  return { dataSource, loading, refresh: loadData };
}

注释原则

何时添加注释

  • 必须注释

    • 导出的函数、方法、结构体、接口
    • 复杂的业务逻辑
    • 非显而易见的实现
    • 公共 API 和组件
  • 无需注释

    • 简单的 getter/setter
    • 显而易见的实现
    • 私有辅助函数(除非逻辑复杂)
go
// ❌ 错误 - 无意义注释
// GetID gets the ID
func (m *Model) GetID() int64 {
    return m.ID
}

// ✅ 正确 - 简单 getter 无需注释
func (m *Model) GetID() int64 {
    return m.ID
}

// ✅ 正确 - 复杂逻辑需要注释
// CalculateScore calculates the weighted score based on multiple factors.
// The formula is: (quality * 0.4) + (speed * 0.3) + (accuracy * 0.3)
func (m *Model) CalculateScore() float64 {
    return (m.Quality * 0.4) + (m.Speed * 0.3) + (m.Accuracy * 0.3)
}

注释质量

go
// ❌ 错误 - 重复代码的注释
// Create a user
user := &User{Name: "test"}

// ❌ 错误 - 过时的注释
// TODO: 这个功能已经实现了,但注释没更新
func Process() {}

// ✅ 正确 - 解释为什么这样做
// 使用 BIGINT 存储时间戳而非 DATETIME,避免时区问题
CreatedAt int64 `json:"created_at" gorm:"column:created_at"`

// ✅ 正确 - 解释重要的业务规则
// 软删除:设置 deleted_at 时间戳,而不是物理删除记录
// 这样可以保留数据用于审计和数据恢复
func (s *Service) Delete(ctx context.Context, id int64) error {
    return s.db.Model(&Model{}).
        Where("id = ?", id).
        Update("deleted_at", time.Now().Unix()).Error
}

禁止的做法

  • 禁止 注释包含错误信息
  • 禁止 注释与代码不一致
  • 避免 过度注释
go
// ❌ 错误 - 注释与代码不一致
// GetByID retrieves a record by name
func (s *Service) GetByID(ctx context.Context, id int64) (*Model, error) {
    // 实际上是通过 ID 查询,不是 name
}

// ❌ 错误 - 过度注释
// i is the index variable
// Loop through the array
// Check if item is not nil
for i, item := range items {
    if item != nil {
        // Process the item
        process(item)
    }
}

// ✅ 正确 - 清晰简洁
for _, item := range items {
    if item != nil {
        process(item)
    }
}

相关文档