# 文件管理模块代码风格规范 ## 概述 本文档定义了文件管理模块的代码风格规范,确保代码一致性、可读性和可维护性。 --- ## 1. 注释规范 ### 1.1 包注释 每个包应该有一个简短的包注释,说明包的用途。 ```go // Package filesystem 提供文件系统操作功能 // // 核心功能: // - 文件读写、删除、列表 // - 路径验证和安全检查 // - ZIP文件操作 // - 审计日志和回收站 package filesystem ``` ### 1.2 函数注释 使用标准Go文档注释风格: ```go // DeletePath 删除文件或目录 // // 参数: // path - 文件或目录路径 // // 返回: // error - 错误信息,nil表示成功 // // 示例: // err := fs.DeletePath("/path/to/file") func (s *FileSystemService) DeletePath(path string) error { // 实现... } ``` ### 1.3 禁止的注释风格 ```go // 禁止使用emoji // 🔒 安全检查 // ✅ 优化 // ⚠️ 警告 // 应使用纯文本 // 安全检查 // 性能优化 // 警告 ``` --- ## 2. 错误处理规范 ### 2.1 错误包装 使用 WrapError 添加上下文: ```go // 推荐做法 data, err := os.ReadFile(path) if err != nil { return "", WrapError("读取文件", path, err) } // 避免裸错误 return "", err // ❌ 不推荐 return "", fmt.Errorf("失败: %w", err) // ✅ 推荐 ``` ### 2.2 错误消息 使用中文描述(面向中文用户): ```go // 推荐 return fmt.Errorf("文件不存在: %s", path) // 避免使用英文 return fmt.Errorf("file not found: %s", path) // ❌ ``` ### 2.3 错误忽略 必须注释说明原因: ```go // 推荐:注释说明原因 if err := logger.Close(); err != nil { // 日志关闭失败,程序即将退出,忽略错误 } // 禁止:无注释忽略 _ = logger.Close() // ❌ ``` --- ## 3. 命名规范 ### 3.1 常量命名 使用大驼峰命名法: ```go const ( MaxZipSize = 100 * 1024 * 1024 DefaultDirPermissions = 0755 AuditFlushInterval = 5 * time.Second ) ``` ### 3.2 变量命名 使用小驼峰命名法: ```go var ( globalService *FileSystemService defaultConfig *Config defaultPermissions os.FileMode = 0644 ) ``` ### 3.3 接口命名 接口名应该是动作或能力的描述,通常以 -er 结尾: ```go type Reader interface { Read(p []byte) (n int, err error) } type Validator interface { Validate(path string) error } ``` --- ## 4. 函数设计规范 ### 4.1 函数长度 推荐单个函数不超过50行。如果超过,考虑拆分子函数: ```go // 推荐:拆分子函数 func DeletePath(path string) error { if err := validatePath(path); err != nil { return err } if err := checkPermissions(path); err != nil { return err } return performDelete(path) } // 避免:长函数 func DeletePath(path string) error { // 100行代码... } ``` ### 4.2 参数数量 函数参数不超过5个。如果超过,使用结构体: ```go // 推荐:使用结构体 type DeleteOptions struct { Path string Force bool SkipRecycle bool IgnoreLock bool Reason string } func DeleteWithOptions(opts DeleteOptions) error { // 实现... } // 避免:过多参数 func DeleteWithOptions(path string, force bool, skipRecycle bool, ignoreLock bool, reason string, timeout int) error { // 参数过多 } ``` ### 4.3 返回值 函数返回值遵循以下顺序: 1. 结果 2. 错误 ```go // 推荐 func ReadFile(path string) ([]byte, error) // 避免多个返回值 func ReadFile(path string) ([]byte, bool, error, int) ``` --- ## 5. 代码组织 ### 5.1 文件组织 每个文件应该有单一的职责: ``` filesystem/ ├── fs.go # 核心文件操作 ├── service.go # 文件系统服务 ├── path_validator.go # 路径验证 ├── filetype_manager.go # 文件类型管理 ├── zip.go # ZIP操作 ├── errors.go # 错误定义 ├── logger.go # 日志记录 └── constants.go # 常量定义 ``` ### 5.2 导入顺序 标准库 → 第三方库 → 项目内部: ```go import ( // 标准库 "context" "fmt" "os" // 第三方库 "github.com/google/uuid" // 项目内部 "go-desk/internal/common" ) ``` --- ## 6. 性能规范 ### 6.1 避免重复计算 使用缓存或预计算: ```go // 推荐:缓存结果 type statsCache struct { mu sync.RWMutex cache map[string]*DirectoryStats } func (c *statsCache) Get(path string) (*DirectoryStats, error) { c.mu.RLock() if stats, ok := c.cache[path]; ok { c.mu.RUnlock() return stats, nil } c.mu.RUnlock() // 计算并缓存 stats, err := GetDirectoryStats(path) if err != nil { return nil, err } c.mu.Lock() c.cache[path] = stats c.mu.Unlock() return stats, nil } // 避免:重复计算 func processData(path string) { stats1, _ := GetDirectoryStats(path) stats2, _ := GetDirectoryStats(path) // 重复计算 } ``` ### 6.2 资源释放 使用 defer 确保资源释放: ```go // 推荐 func ReadFile(path string) ([]byte, error) { file, err := os.Open(path) if err != nil { return nil, err } defer file.Close() // 确保关闭 return io.ReadAll(file) } ``` --- ## 7. 并发安全 ### 7.1 共享状态 使用互斥锁保护共享状态: ```go type SafeCounter struct { mu sync.RWMutex count int } func (c *SafeCounter) Increment() { c.mu.Lock() defer c.mu.Unlock() c.count++ } func (c *SafeCounter) Get() int { c.mu.RLock() defer c.mu.RUnlock() return c.count } ``` ### 7.2 避免数据竞争 不要在goroutine中直接共享变量: ```go // 推荐:传递参数 for i := 0; i < 10; i++ { go func(n int) { fmt.Println(n) }(i) } // 避免:闭包捕获 for i := 0; i < 10; i++ { go func() { fmt.Println(i) // 数据竞争 }() } ``` --- ## 8. 测试规范 ### 8.1 测试文件命名 测试文件命名为 `xxx_test.go`: ```go // fs_test.go package filesystem import "testing" func TestDeletePath(t *testing.T) { // 测试代码 } ``` ### 8.2 表格驱动测试 使用表格驱动测试多种场景: ```go func TestValidatePath(t *testing.T) { tests := []struct { name string path string wantErr bool }{ {"正常路径", "/tmp/test.txt", false}, {"路径遍历", "/tmp/../etc/passwd", true}, {"空路径", "", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidatePath(tt.path) if (err != nil) != tt.wantErr { t.Errorf("ValidatePath() error = %v, wantErr %v", err, tt.wantErr) } }) } } ``` --- ## 9. 文档规范 ### 9.1 README 每个模块应该有README说明: ```markdown # 文件系统模块 ## 功能 - 文件读写 - 路径验证 - ZIP操作 ## 使用示例 ... ## 配置 ... ``` ### 9.2 API文档 导出的函数和类型必须有文档注释。 --- ## 10. 代码审查清单 提交代码前,确保: - [ ] 移除所有emoji注释 - [ ] 函数有文档注释 - [ ] 错误处理完善(无忽略错误) - [ ] 命名符合规范 - [ ] 无魔法数字(使用常量) - [ ] 无重复代码(遵循DRY) - [ ] 导入顺序正确 - [ ] 资源正确释放(defer) --- *版本: 1.0* *最后更新: 2026-01-27*