7.4 KiB
7.4 KiB
文件管理模块代码风格规范
概述
本文档定义了文件管理模块的代码风格规范,确保代码一致性、可读性和可维护性。
1. 注释规范
1.1 包注释
每个包应该有一个简短的包注释,说明包的用途。
// Package filesystem 提供文件系统操作功能
//
// 核心功能:
// - 文件读写、删除、列表
// - 路径验证和安全检查
// - ZIP文件操作
// - 审计日志和回收站
package filesystem
1.2 函数注释
使用标准Go文档注释风格:
// DeletePath 删除文件或目录
//
// 参数:
// path - 文件或目录路径
//
// 返回:
// error - 错误信息,nil表示成功
//
// 示例:
// err := fs.DeletePath("/path/to/file")
func (s *FileSystemService) DeletePath(path string) error {
// 实现...
}
1.3 禁止的注释风格
// 禁止使用emoji
// 🔒 安全检查
// ✅ 优化
// ⚠️ 警告
// 应使用纯文本
// 安全检查
// 性能优化
// 警告
2. 错误处理规范
2.1 错误包装
使用 WrapError 添加上下文:
// 推荐做法
data, err := os.ReadFile(path)
if err != nil {
return "", WrapError("读取文件", path, err)
}
// 避免裸错误
return "", err // ❌ 不推荐
return "", fmt.Errorf("失败: %w", err) // ✅ 推荐
2.2 错误消息
使用中文描述(面向中文用户):
// 推荐
return fmt.Errorf("文件不存在: %s", path)
// 避免使用英文
return fmt.Errorf("file not found: %s", path) // ❌
2.3 错误忽略
必须注释说明原因:
// 推荐:注释说明原因
if err := logger.Close(); err != nil {
// 日志关闭失败,程序即将退出,忽略错误
}
// 禁止:无注释忽略
_ = logger.Close() // ❌
3. 命名规范
3.1 常量命名
使用大驼峰命名法:
const (
MaxZipSize = 100 * 1024 * 1024
DefaultDirPermissions = 0755
AuditFlushInterval = 5 * time.Second
)
3.2 变量命名
使用小驼峰命名法:
var (
globalService *FileSystemService
defaultConfig *Config
defaultPermissions os.FileMode = 0644
)
3.3 接口命名
接口名应该是动作或能力的描述,通常以 -er 结尾:
type Reader interface {
Read(p []byte) (n int, err error)
}
type Validator interface {
Validate(path string) error
}
4. 函数设计规范
4.1 函数长度
推荐单个函数不超过50行。如果超过,考虑拆分子函数:
// 推荐:拆分子函数
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个。如果超过,使用结构体:
// 推荐:使用结构体
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 返回值
函数返回值遵循以下顺序:
- 结果
- 错误
// 推荐
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 导入顺序
标准库 → 第三方库 → 项目内部:
import (
// 标准库
"context"
"fmt"
"os"
// 第三方库
"github.com/google/uuid"
// 项目内部
"go-desk/internal/common"
)
6. 性能规范
6.1 避免重复计算
使用缓存或预计算:
// 推荐:缓存结果
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 确保资源释放:
// 推荐
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 共享状态
使用互斥锁保护共享状态:
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中直接共享变量:
// 推荐:传递参数
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:
// fs_test.go
package filesystem
import "testing"
func TestDeletePath(t *testing.T) {
// 测试代码
}
8.2 表格驱动测试
使用表格驱动测试多种场景:
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说明:
# 文件系统模块
## 功能
- 文件读写
- 路径验证
- ZIP操作
## 使用示例
...
## 配置
...
9.2 API文档
导出的函数和类型必须有文档注释。
10. 代码审查清单
提交代码前,确保:
- 移除所有emoji注释
- 函数有文档注释
- 错误处理完善(无忽略错误)
- 命名符合规范
- 无魔法数字(使用常量)
- 无重复代码(遵循DRY)
- 导入顺序正确
- 资源正确释放(defer)
版本: 1.0 最后更新: 2026-01-27