🎨 style(markdown): format all markdown files with prettier
- 使用 prettier 格式化所有 markdown 文件 - prose-wrap: always, print-width: 80 - 保持代码块和表格格式 - 提升可读性和一致性 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
+76
-37
@@ -1,54 +1,74 @@
|
||||
# TSL 命名规范(Naming)
|
||||
|
||||
本仓库命名规则与 Google C++ Style Guide 对齐:通过名字的“形状”快速判断实体类型(类型/函数/变量/常量等),减少阅读成本。
|
||||
本仓库命名规则与 Google C++ Style
|
||||
Guide 对齐:通过名字的“形状”快速判断实体类型(类型/函数/变量/常量等),减少阅读成本。
|
||||
|
||||
## 1. 选名原则
|
||||
|
||||
- **可读一致**:名字清晰可读,并随可见范围调整具体程度。
|
||||
- 可见范围越大(越对外),名字越应具体、少省略。
|
||||
- 本指南中“对外可见”指:`unit interface`、`class public`、顶层 `function`。
|
||||
- **标识符语言**:标识符(类型/函数/property/变量/参数等)统一使用英文;禁止中文与拼音(注释可中英混合,见 `docs/tsl/code_style.md`)。
|
||||
- **标识符语言**:标识符(类型/函数/property/变量/参数等)统一使用英文;禁止中文与拼音(注释可中英混合,见
|
||||
`docs/tsl/code_style.md`)。
|
||||
- **少用生僻缩写**:能写全称就写全称。
|
||||
- 允许使用团队已约定、大家都懂的常见缩写;若缩写不够通用,优先写全称或在评审/文档中先达成约定。
|
||||
- **驼峰/帕斯卡中的缩写规则**:缩写(首字母缩写/词组缩写)在 `PascalCase`/`camelCase` 中**按一个单词处理**,写成“首字母大写其余小写”,不要写一串全大写。
|
||||
- **驼峰/帕斯卡中的缩写规则**:缩写(首字母缩写/词组缩写)在
|
||||
`PascalCase`/`camelCase`
|
||||
中**按一个单词处理**,写成“首字母大写其余小写”,不要写一串全大写。
|
||||
- 示例:`UserId`(不是 `UserID`)、`UrlTable`(不是 `URLTable`)、
|
||||
`StartRpcServer`(不是 `StartRPCServer`)、`HttpClient`(不是 `HTTPClient`)。
|
||||
`StartRpcServer`(不是 `StartRPCServer`)、`HttpClient`(不是
|
||||
`HTTPClient`)。
|
||||
- **避免无意义词**:如 `data`、`info`、`tmp`、`handle` 等。
|
||||
- 可以作为限定词的一部分(例如 `user_data`),但不要单独用作名字(例如仅叫 `data`)。
|
||||
- 可以作为限定词的一部分(例如 `user_data`),但不要单独用作名字(例如仅叫
|
||||
`data`)。
|
||||
|
||||
## 2. 命名风格总览
|
||||
|
||||
对于以下规则,“单词”指英文中不带空格的词。
|
||||
|
||||
- `snake_case`:全小写,下划线分隔单词,用于普通变量/参数等;私有类成员变量使用 `snake_case_`(见 5.2)。
|
||||
- `snake_case`:全小写,下划线分隔单词,用于普通变量/参数等;私有类成员变量使用
|
||||
`snake_case_`(见 5.2)。
|
||||
- `PascalCase`(`UpperCamelCase`):每个单词首字母大写,无下划线,用于类型、顶层函数/“动作型”方法、property,以及(少量)公有成员字段(访问器/设置器方法见 7 的例外约定)。
|
||||
- 自定义标识符只使用本指南约定的 `PascalCase`/`snake_case`;`lowerCamelCase` 仅用于沿用内置/标准库/第三方 API 的既有命名。
|
||||
- 自定义标识符只使用本指南约定的 `PascalCase`/`snake_case`;`lowerCamelCase`
|
||||
仅用于沿用内置/标准库/第三方 API 的既有命名。
|
||||
|
||||
**大小写与关键字约定**
|
||||
|
||||
- TSL 语言大小写无关,但本指南仍要求按约定使用大小写以提升可读性;不要用仅大小写不同的名字区分不同实体;同一标识符在仓库中应保持一致写法。
|
||||
- 所有语法关键字统一使用全小写书写,例如 `if`、`for`、`class`、`function`、`unit`、`return` 等。
|
||||
- 调用内置/标准库/第三方 API 时,推荐保持对方官方大小写形式(`aaBBCC`/lowerCamelCase),例如 `getSysParams("xxx")`;自定义 wrapper 仍按本指南使用 `PascalCase`。
|
||||
- 所有语法关键字统一使用全小写书写,例如
|
||||
`if`、`for`、`class`、`function`、`unit`、`return` 等。
|
||||
- 调用内置/标准库/第三方 API 时,推荐保持对方官方大小写形式(`aaBBCC`/lowerCamelCase),例如
|
||||
`getSysParams("xxx")`;自定义 wrapper 仍按本指南使用 `PascalCase`。
|
||||
|
||||
## 3. 类型命名(Type Names)
|
||||
|
||||
TSL 的顶层声明只有三种:`class`、`unit`、`function`(仅适用于 `.tsf`)。
|
||||
因此 `.tsf` 文件基名必须与顶层声明同名(见“4. 文件命名与顶层声明”)。
|
||||
TSL 的顶层声明只有三种:`class`、`unit`、`function`(仅适用于 `.tsf`)。因此
|
||||
`.tsf` 文件基名必须与顶层声明同名(见“4. 文件命名与顶层声明”)。
|
||||
|
||||
- **类(class)与单元(unit)**使用 `PascalCase`,不带下划线;名称应为名词/名词短语(通常单数),避免动词开头。
|
||||
- 不推荐 `*Unit` 作为 `unit` 的后缀(`unit` 本身已表达语义);需要表达用途时,可使用 `*Shared`/`*Common`/`*Enums` 等更具体后缀(按团队约定)。
|
||||
- **顶层函数(function)**使用 `PascalCase`;名称优先动词/动词短语(例如 `Load`/`Parse`/`Build`),详见函数命名章节。
|
||||
- **类(class)与单元(unit)**使用
|
||||
`PascalCase`,不带下划线;名称应为名词/名词短语(通常单数),避免动词开头。
|
||||
- 不推荐 `*Unit` 作为 `unit` 的后缀(`unit`
|
||||
本身已表达语义);需要表达用途时,可使用 `*Shared`/`*Common`/`*Enums`
|
||||
等更具体后缀(按团队约定)。
|
||||
- **顶层函数(function)**使用 `PascalCase`;名称优先动词/动词短语(例如
|
||||
`Load`/`Parse`/`Build`),详见函数命名章节。
|
||||
- 示例:`UserAccount`、`OrderShared`、`LoadMarketData()`。
|
||||
|
||||
## 4. 文件命名与顶层声明(File Names)
|
||||
|
||||
TSL 的语法要求(仅 `.tsf`):每个 `.tsf` 文件只能有一个顶层声明,且**文件基名必须与该顶层声明名字一致**。
|
||||
TSL 的语法要求(仅 `.tsf`):每个 `.tsf`
|
||||
文件只能有一个顶层声明,且**文件基名必须与该顶层声明名字一致**。
|
||||
|
||||
- 顶层声明可能是 `class`、`unit` 或 `function`(见类型命名)。
|
||||
- `.tsf` 代码文件:用于库/模块等“顶层声明”的承载文件;顶层声明可为 `class`/`unit`/`function`,文件基名需与之同名。
|
||||
- `.tsl` 脚本文件:用于入口/编排层;允许直接写语句(如 `a := 1; echo a;`),不要求顶层声明,也不强制文件基名与函数名一致;可复用逻辑应下沉到 `.tsf`(见 `docs/tsl/code_style.md`)。
|
||||
- `.tsf` 代码文件:用于库/模块等“顶层声明”的承载文件;顶层声明可为
|
||||
`class`/`unit`/`function`,文件基名需与之同名。
|
||||
- `.tsl` 脚本文件:用于入口/编排层;允许直接写语句(如
|
||||
`a := 1; echo a;`),不要求顶层声明,也不强制文件基名与函数名一致;可复用逻辑应下沉到
|
||||
`.tsf`(见 `docs/tsl/code_style.md`)。
|
||||
- 注:`.tsf` 也是 TSL 源文件,命名/风格与 `.tsl` 遵循同一套规则。
|
||||
- **硬规则(仅 `.tsf`)**:重命名顶层声明时必须同步重命名文件基名,否则语法/加载规则无法识别;批量重命名可参考 `$bulk-refactor-workflow`。
|
||||
- **硬规则(仅
|
||||
`.tsf`)**:重命名顶层声明时必须同步重命名文件基名,否则语法/加载规则无法识别;批量重命名可参考
|
||||
`$bulk-refactor-workflow`。
|
||||
|
||||
命名建议:
|
||||
|
||||
@@ -66,20 +86,26 @@ TSL 的语法要求(仅 `.tsf`):每个 `.tsf` 文件只能有一个顶层
|
||||
### 5.1 普通变量与参数
|
||||
|
||||
- **局部变量、函数参数、非成员变量**使用 `snake_case`。
|
||||
- 若参数名与 TSL 关键字冲突导致编译失败,使用前导下划线的 `snake_case` 作为例外,例如 `_type`(`type` 是常见冲突关键字)。
|
||||
- 前导下划线 `_` **仅用于上述关键字冲突的参数场景**,不要用于其他局部变量、成员变量、函数/类型/单元名称或全局变量。
|
||||
- 建议把单位写进名字(尤其时间/金额/比例):例如 `timeout_ms`、`spread_bp`、`ratio_pct`。
|
||||
- 若参数名与 TSL 关键字冲突导致编译失败,使用前导下划线的 `snake_case`
|
||||
作为例外,例如 `_type`(`type` 是常见冲突关键字)。
|
||||
- 前导下划线 `_`
|
||||
**仅用于上述关键字冲突的参数场景**,不要用于其他局部变量、成员变量、函数/类型/单元名称或全局变量。
|
||||
- 建议把单位写进名字(尤其时间/金额/比例):例如
|
||||
`timeout_ms`、`spread_bp`、`ratio_pct`。
|
||||
- 示例:`table_name`、`max_retry_count`、`user_id`(短名例外见 5.5)。
|
||||
|
||||
### 5.2 类成员(Class Data Members)
|
||||
|
||||
- **私有成员变量**使用 `snake_case_`(尾随下划线)。
|
||||
- 尾随下划线 `_` **仅用于私有成员变量**,不要用于局部变量、参数、公有成员字段、property 名称或顶层全局变量。
|
||||
- **公有成员变量**若必须存在,使用 `PascalCase`;但**不推荐外部直接访问公有字段**。
|
||||
- 尾随下划线 `_`
|
||||
**仅用于私有成员变量**,不要用于局部变量、参数、公有成员字段、property 名称或顶层全局变量。
|
||||
- **公有成员变量**若必须存在,使用
|
||||
`PascalCase`;但**不推荐外部直接访问公有字段**。
|
||||
- 对外暴露的成员优先使用 **property**:
|
||||
- property 名称使用 `PascalCase`(视为对外 API)。
|
||||
- property 的 `read/write` 指向真实成员(通常为私有 `snake_case_`)。
|
||||
- 布尔 property 使用 `Is`/`Has`/`Can`/`Should` 等前缀的 `PascalCase`(例如 `IsReady`),对应私有成员可用 `is_ready_` 等。
|
||||
- 布尔 property 使用 `Is`/`Has`/`Can`/`Should` 等前缀的 `PascalCase`(例如
|
||||
`IsReady`),对应私有成员可用 `is_ready_` 等。
|
||||
- 示例:
|
||||
|
||||
```tsl
|
||||
@@ -95,7 +121,8 @@ end;
|
||||
|
||||
### 5.3 全局/静态变量
|
||||
|
||||
- 不推荐使用顶层全局/静态可变变量;优先封装到 `unit`/`class` 中,通过函数或 property 访问。
|
||||
- 不推荐使用顶层全局/静态可变变量;优先封装到 `unit`/`class`
|
||||
中,通过函数或 property 访问。
|
||||
- 合理例外(仍需集中管理,避免到处读写):
|
||||
- 进程级只读配置缓存(启动后不再变)。
|
||||
- 有上限/可清理的缓存(明确容量/TTL/清理点)。
|
||||
@@ -113,20 +140,25 @@ end;
|
||||
// Global because: <why it needs to be global (if unclear)>
|
||||
```
|
||||
|
||||
- 全局/静态常量仍按常量规则使用 `kPascalCase`(建议同样写一句用途注释,便于检索与维护)。
|
||||
- 全局/静态常量仍按常量规则使用
|
||||
`kPascalCase`(建议同样写一句用途注释,便于检索与维护)。
|
||||
|
||||
### 5.4 布尔变量
|
||||
|
||||
- 布尔变量建议区分两类语义:
|
||||
- **状态/谓词(predicate)**:描述“是否满足某条件/是否处于某状态”,使用 `is_ / has_ / can_ / should_` 等前缀表达语义。
|
||||
- **状态/谓词(predicate)**:描述“是否满足某条件/是否处于某状态”,使用
|
||||
`is_ / has_ / can_ / should_` 等前缀表达语义。
|
||||
- 示例:`is_ready`、`has_error`、`can_retry`。
|
||||
- **选项/开关(flag/option)**:描述“是否启用某行为/模式”,允许使用不带 `is_` 的 `snake_case` 短语(更贴近配置项语义)。
|
||||
- **选项/开关(flag/option)**:描述“是否启用某行为/模式”,允许使用不带 `is_`
|
||||
的 `snake_case` 短语(更贴近配置项语义)。
|
||||
- 示例:`dry_run`、`include_header`、`enable_cache`、`use_cache`。
|
||||
- 尽量使用正向命名,避免双重否定:`is_valid` 优于 `is_not_valid`;`disable_cache` 这类命名需谨慎(容易在调用点读错)。
|
||||
- 尽量使用正向命名,避免双重否定:`is_valid` 优于
|
||||
`is_not_valid`;`disable_cache` 这类命名需谨慎(容易在调用点读错)。
|
||||
|
||||
### 5.5 短名例外
|
||||
|
||||
- 在极小作用域内可用习惯短名:仅限 `for/while` 的索引变量或约 5–10 行内的临时值。
|
||||
- 在极小作用域内可用习惯短名:仅限 `for/while`
|
||||
的索引变量或约 5–10 行内的临时值。
|
||||
- 允许短名清单(建议严格执行):`i/j/k`(索引)、`n`(计数);其他一律使用有含义的名字。
|
||||
- 作用域一旦扩大(跨多个分支/循环、跨函数、跨文件),必须改为有含义的名字。
|
||||
|
||||
@@ -134,14 +166,17 @@ end;
|
||||
|
||||
- **数组/列表/可迭代集合**使用复数名词的 `snake_case`:`users`、`order_items`。
|
||||
- 若复数形式不直观或为不可数名词,使用后缀明确类型:`news_list`、`price_items`。
|
||||
- **映射/字典(key→value)**使用 `snake_case` 并加后缀 `_map`;必要时可用 `_by_<key>` 表达键语义(仍需保留 `_map`):`user_map`、`price_by_symbol_map`。
|
||||
- **映射/字典(key→value)**使用 `snake_case` 并加后缀 `_map`;必要时可用
|
||||
`_by_<key>` 表达键语义(仍需保留 `_map`):`user_map`、`price_by_symbol_map`。
|
||||
- **集合/去重集合**使用后缀 `_set`:`user_id_set`、`symbol_set`。
|
||||
|
||||
## 6. 常量命名(Constant Names)
|
||||
|
||||
- **模块级/全局级固定常量**(写死、与入参无关、加载后不变)使用 `kPascalCase`,以 `k` 开头。
|
||||
- **模块级/全局级固定常量**(写死、与入参无关、加载后不变)使用
|
||||
`kPascalCase`,以 `k` 开头。
|
||||
- 示例:`kDaysInAWeek`、`kAndroid8_0_0`。
|
||||
- 常量名建议带单位(尤其时间/金额/比例):例如 `kTimeoutMs`、`kSpreadBp`、`kRatioPct`。
|
||||
- 常量名建议带单位(尤其时间/金额/比例):例如
|
||||
`kTimeoutMs`、`kSpreadBp`、`kRatioPct`。
|
||||
- 对于**局部 const 但值来自参数/运行时**的变量:
|
||||
- 可用普通变量名 `snake_case`;
|
||||
- 不要用 `k` 前缀误导读者认为其全局固定。
|
||||
@@ -150,7 +185,8 @@ end;
|
||||
|
||||
TSL 没有内置 `enum`,推荐使用 `unit` + `const` 在 `interface` 区域模拟枚举集合。
|
||||
|
||||
- `unit` 名称使用 `PascalCase`,建议以 `Enumerations` 结尾表达用途(例如 `DocxEnumerations`)。
|
||||
- `unit` 名称使用 `PascalCase`,建议以 `Enumerations` 结尾表达用途(例如
|
||||
`DocxEnumerations`)。
|
||||
- 枚举值使用 `const` 定义并放在 `interface` 中:
|
||||
- 项目自定义枚举值:默认使用 `kPascalCase`(属于模块级固定常量)。
|
||||
- 外部/互操作枚举值:允许沿用对方既有前缀与命名(例外场景)。
|
||||
@@ -178,16 +214,19 @@ end.
|
||||
## 7. 函数与方法命名(Function Names)
|
||||
|
||||
- 顶层函数与“动作型/业务型”方法使用 `PascalCase`。
|
||||
- 访问器/设置器方法(仅当 property 无法表达语义时才使用)允许使用 `snake_case` 的小写形式,以贴近“字段/状态”的语义(按团队约定的例外)。
|
||||
- 访问器/设置器方法(仅当 property 无法表达语义时才使用)允许使用 `snake_case`
|
||||
的小写形式,以贴近“字段/状态”的语义(按团队约定的例外)。
|
||||
- **特殊函数/运算符重载为语法固定名,必须使用全小写**:
|
||||
- 构造/初始化函数:`create`。
|
||||
- 析构/释放函数:`destroy`。
|
||||
- 运算符重载:`operator+()` 等,按语法使用小写 `operator<op>()` 形式。
|
||||
- 示例:`AddTableEntry()`、`DeleteUrl()`、`OpenFileOrDie()`。
|
||||
- **推荐使用 property 语法**对外暴露访问器:property 名 `PascalCase`,`read/write` 绑定成员变量(见类成员章节)。
|
||||
- **推荐使用 property 语法**对外暴露访问器:property 名
|
||||
`PascalCase`,`read/write` 绑定成员变量(见类成员章节)。
|
||||
- 不推荐新增显式 getter/setter;仅当 property 无法表达语义时,才使用 getter/setter:
|
||||
- getter:与字段同形的 `snake_case`(如 `count()`、`is_ready()`)。
|
||||
- setter:使用 `set_` 前缀的 `snake_case`(如 `set_count(x)`、`set_ready(x)`)。
|
||||
- setter:使用 `set_` 前缀的 `snake_case`(如
|
||||
`set_count(x)`、`set_ready(x)`)。
|
||||
|
||||
## 8. 宏与编译期开关(Macro Names)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user