关于 coding-standards
Coding Standards 是供 Agent 和代码审查者使用的跨语言编码规范参考,涵盖命名、函数设计、错误处理、代码结构、反模式及 SOLID 原则。
主要功能
- 01跨语言命名约定
- 02函数设计指南
- 03错误处理规则
- 04代码结构实践
- 05反模式参考
- 06SOLID 原则检查清单
适用场景
- 01审查多种语言的代码
- 02检查函数复杂度与设计
- 03改进错误处理
- 04识别常见反模式
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ zereight/ gitlab-mcp --skill coding-standards安装后在 Claude Code 中输入/coding-standards确认已加载。
详细介绍
编码规范
D9 权威参考。 这是跨语言编码规范的唯一事实来源。 特定语言的审查者(
@typescript-reviewer、@python-reviewer等)会纳入这些规则。 Agent 引用此技能时应写为“另请参阅:/coding-standards。”
命名约定
变量与函数
| 语言 | 变量 | 函数 | 常量 |
|---|---|---|---|
| TypeScript / JavaScript | camelCase | camelCase | SCREAMING_SNAKE_CASE |
| Python | snake_case | snake_case | SCREAMING_SNAKE_CASE |
| Go | camelCase | camelCase | CamelCase(导出) |
| Rust | snake_case | snake_case | SCREAMING_SNAKE_CASE |
| Java | camelCase | camelCase | SCREAMING_SNAKE_CASE |
| C# | camelCase | PascalCase | PascalCase |
| Swift | camelCase | camelCase | camelCase |
类 / 类型 / 接口
所有语言均使用 PascalCase,无一例外。
布尔值
使用 is、has、can、should 作为前缀:isLoading、hasError、canEdit、shouldRefresh。
集合
使用复数名词:users、errors、items,而非 userList、errorArray。
避免
- 除循环计数器外,避免使用单字母变量(循环中可使用
i、j、k) - 避免节省不到 3 个字符的缩写:
usr→user、mgr→manager - 避免冗余的类型名称:
UserInterface、UserClass、UserObject→ 直接使用User
函数设计
- 最大长度: 50 行(严格建议;超过 80 行时必须考虑拆分)
- 单一职责: 一个函数只做一件事——如果描述中出现“并且”,就应拆分
- 最多参数: 3 个;更多时使用选项/配置对象
- 圈复杂度: ≤ 10;> 15 时必须重构
- 嵌套深度: ≤ 3 层;使用提前返回来简化结构
提前返回模式(首选)
// BEFORE — deep nesting
function handle(input) {
if (input) {
if (input.valid) {
return process(input);
}
}
return null;
}
// AFTER — early returns
function handle(input) {
if (!input || !input.valid) return null;
return process(input);
}
错误处理
- 绝不静默吞掉错误:
catch (e) {}永远是错误写法 - 错误消息必须包含上下文:
"Failed to fetch user id=42",而非"Error" - 传播或处理: 要么在合适的层级处理错误,要么重新抛出——绝不能两者兼做,也不能两者都不做
- 类型化错误(TypeScript): 使用
class NotFoundError extends Error { constructor(id: string) ... },而非通用的new Error - Python 异常: 捕获特定异常类型;禁止裸
except: - Go 错误: 始终检查返回的错误;使用
errors.Is()/errors.As()进行比较 - Rust 结果: 使用
?传播;库代码中不得使用.unwrap()
代码结构
优先使用不可变数据
- JS/TS 中优先使用
const而非let;Swift/Kotlin 中优先使用val而非var;适当时使用final - 构造后不再重新赋值的字段应标记为
readonly - 函数参数优先使用不可变数据结构
避免魔法数字
// BAD
if (retries > 3) { ... }
setTimeout(fn, 5000);
// GOOD
const MAX_RETRIES = 3;
const POLL_INTERVAL_MS = 5000;
if (retries > MAX_RETRIES) { ... }
setTimeout(fn, POLL_INTERVAL_MS);
不保留注释掉的代码
如果代码已无用 → 删除(Git 历史会保留它)。 如果近期需要 → 应放入一个分支。 如果用于解释不明显的决策 → 将其保留为注释,而不是注释掉的代码。
反模式参考
| 模式 | 严重性 | 原因 |
|---|---|---|
| 可变全局状态 | HIGH | 副作用不可预测;依赖关系被隐藏 |
| Promise 未等待 | HIGH | 未处理的异步错误会被静默吞掉 |
TypeScript 中的 any | MEDIUM | 绕过调用边界的类型安全检查 |
生产代码中的 console.log | LOW | 产生冗余日志;在敏感场景下可能导致数据泄露 |
未引用问题跟踪器的 TODO | LOW | 会变成永久的技术债务 |
| 上帝对象 | HIGH | 单个类承担过多职责 |
| 行内魔法数字 | MEDIUM | 意图不明确;增加维护风险 |
| 复制粘贴逻辑 | MEDIUM | 随时间推移悄然产生差异 |
| 捕获错误后不添加上下文便重新抛出 | MEDIUM | 堆栈跟踪失去意义 |
| 嵌套三元运算符 | MEDIUM | 难以阅读;应改用 if/else 或 switch |
SOLID 原则检查清单
- Single Responsibility(单一职责):这个类/函数是否只做一件事?
- Open/Closed(开闭原则):是否通过组合/接口扩展,而不是修改继承关系?
- Liskov Substitution(里氏替换):子类型是否总能替换基类型,而不影响调用方?
- Interface Segregation(接口隔离):是否避免臃肿的接口——客户端不应依赖它们不会使用的方法?
- Dependency Inversion(依赖倒置):是否依赖抽象(接口),而不是具体实现?
另请参阅
@code-reviewer— 在代码审查过程中应用这些规则@typescript-reviewer、@python-reviewer等 — 以这些规则为基础的语言专属规则@security-reviewer— 安全专属标准(OWASP、机密信息、加密)
评论
支持 Markdown