playbook/docs/tsl/naming.md

152 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# TSL 命名规范Naming
本仓库命名规则与 Google C++ Style Guide 对齐:通过名字的“形状”快速判断实体类型(类型/函数/变量/常量等),减少阅读成本。
## 1. 选名原则
- **可读一致**:名字清晰可读,并随可见范围调整具体程度。
- **少用生僻缩写**:能写全称就写全称。
- **驼峰/帕斯卡中的缩写规则**:缩写(首字母缩写/词组缩写)在 `PascalCase`/`camelCase` 中**按一个单词处理**,写成“首字母大写其余小写”,不要写一串全大写。
- 示例:`UserId`(不是 `UserID`)、`UrlTable`(不是 `URLTable`)、
`StartRpcServer`(不是 `StartRPCServer`)、`HttpClient`(不是 `HTTPClient`)。
- **避免无意义词**:如 `data`、`info`、`tmp`、`handle` 等。
## 2. 命名风格总览
对于以下规则,“单词”指英文中不带空格的词。
- `snake_case`:全小写,下划线分隔单词,用于普通变量/参数等;私有类成员变量在此基础上末尾加下划线。
- `PascalCase``UpperCamelCase`):每个单词首字母大写,无下划线,用于类型、顶层函数/方法、property以及少量公有成员字段。
**大小写与关键字约定**
- TSL 语言大小写无关,但本指南仍要求按约定使用大小写以提升可读性;不要用仅大小写不同的名字区分不同实体。
- 所有语法关键字统一使用全小写书写,例如 `if`、`for`、`class`、`function`、`unit`、`return` 等。
- 调用内置/标准库方法时,推荐保持官方大小写形式(`aaBBCC`/lowerCamelCase例如 `getSysParams("xxx")`
## 3. 类型命名Type Names
TSL 的顶层声明只有三种:`class`、`unit`、`function`。
- **类class与单元unit**使用 `PascalCase`,不带下划线。
- **顶层函数function**使用 `PascalCase`,详见函数命名章节。
- 示例:`UserAccount`、`OrderUnit`、`LoadMarketData()`。
## 4. 文件命名与顶层声明File Names
TSL 的语法要求:每个文件只能有一个顶层声明,且**文件基名必须与该顶层声明名字一致**。
- 顶层声明可能是 `class`、`unit` 或 `function`(见类型命名)。
- `.tsl` 脚本文件:顶层声明只能是 `function`,因此文件基名 = 顶层函数名。
- `.tsf` 代码文件:顶层声明可为 `class`/`unit`/`function`,文件基名需与之同名。
命名建议:
- 基名统一使用 `PascalCase`,与顶层声明的推荐写法一致。
- 示例:
- `LoadMarketData.tsl` 中定义 `function LoadMarketData(...)`.
- `UserAccount.tsf` 中定义 `type UserAccount = class ... end;`.
- `DocxEnumerations.tsf` 中定义 `unit DocxEnumerations; ... end.`
TSL 大小写无关,实际编译时按大小写比较不会出错,但仍应保持文件名与声明名的推荐写法一致以便检索与协作。
## 5. 变量命名Variable Names
### 5.1 普通变量与参数
- **局部变量、函数参数、非成员变量**使用 `snake_case`
- 若参数名与 TSL 关键字冲突导致编译失败,使用前导下划线的 `snake_case` 作为例外,例如 `_type`、`_unit`。
- 前导下划线 `_` **仅用于上述关键字冲突的参数场景**,不要用于其他局部变量、成员变量、函数/类型/单元名称或全局变量。
- 示例:`table_name`、`max_retry_count`、`user_id`。
### 5.2 类成员Class Data Members
- **私有成员变量**使用 `snake_case_`(尾随下划线)。
- 尾随下划线 `_` **仅用于私有成员变量**不要用于局部变量、参数、公有成员字段、property 名称或顶层全局变量。
- **公有成员变量**若必须存在,使用 `PascalCase`;但**不推荐外部直接访问公有字段**。
- 对外暴露的成员优先使用 **property**
- property 名称使用 `PascalCase`(视为对外 API
- property 的 `read/write` 指向真实成员(通常为私有 `snake_case_`)。
- 示例:
```tsl
type User = class
public
property UserId read user_id_ write user_id_;
private
user_id_;
end;
```
### 5.3 全局/静态变量
- 不推荐使用顶层全局/静态可变变量;优先封装到 `unit`/`class` 中,通过函数或 property 访问。
- 若必须声明顶层全局/静态变量,使用 `g_snake_case` 前缀显式标识其全局性质,例如 `g_user_cache`、`g_market_state`。
- 全局/静态常量仍按常量规则使用 `kPascalCase`
### 5.4 布尔变量
- 使用 `is_ / has_ / can_ / should_` 等前缀表达语义。
- 示例:`is_ready`、`has_error`、`can_retry`。
### 5.5 短名例外
- 在极小作用域内可用习惯短名:`i`、`j`、`n`、`t` 等。
- 作用域一旦扩大,必须改为有含义的名字。
### 5.6 集合与复数命名Collections
- **数组/列表/可迭代集合**使用复数名词的 `snake_case``users`、`order_items`。
- 若复数形式不直观或为不可数名词,使用后缀明确类型:`news_list`、`price_items`。
- **映射/字典key→value**使用 `snake_case` 并加后缀 `_map`,必要时可用 `_by_<key>` 表达键语义:`user_map`、`price_by_symbol`。
- **集合/去重集合**使用后缀 `_set``user_id_set`、`symbol_set`。
## 6. 常量命名Constant Names
- **编译期/全局期固定的常量**使用 `kPascalCase`,以 `k` 开头。
- 示例:`kDaysInAWeek`、`kAndroid8_0_0`。
- 对于**局部 const 但值来自参数/运行时**的变量:
- 可用普通变量名 `snake_case`
- 不要用 `k` 前缀误导读者认为其全局固定。
### 6.1 单元枚举模拟Unit Enumerations
TSL 没有内置 `enum`,推荐使用 `unit` + `const``interface` 区域模拟枚举集合。
- `unit` 名称使用 `PascalCase`,建议以 `Enumerations`/`Enums` 结尾表达用途。
- 枚举值使用 `const` 定义并放在 `interface` 中;命名优先沿用外部/业务域既有前缀与风格(属于例外场景)。
示例:
```tsl
unit DocxEnumerations;
interface
// WdAlertLevel
const wdAlertsAll = -1;
end.
```
## 7. 函数与方法命名Function Names
- 所有**普通**函数/方法(包含 `public`/`private`)均使用 `PascalCase`
- **特殊函数/运算符重载为语法固定名,必须使用全小写**
- 构造/初始化函数:`create`。
- 析构/释放函数:`destroy`。
- 运算符重载:`operator+()` 等,按语法使用小写 `operator<op>()` 形式。
- 示例:`AddTableEntry()`、`DeleteUrl()`、`OpenFileOrDie()`。
- **推荐使用 property 语法**对外暴露访问器property 名 `PascalCase``read/write` 绑定成员变量(见类成员章节)。
- 不推荐新增显式 getter/setter仅当 property 无法表达语义时,才使用 getter/setter命名可与字段同形的 `snake_case`(如 `count()`、`set_count(x)`)。
## 8. 宏与编译期开关Macro Names
- 能不用宏就不用。
- 必须使用时,命名为全大写加下划线,并带项目/业务前缀:
- `TSL_ROUND(x)`、`TSL_ENABLE_FOO`。
## 9. 例外Exceptions
- 当命名需要与外部既有 API/协议保持一致时,可沿用对方风格。
- 例如对接 C/C++ 库、历史接口、跨语言互操作代码等。