152 lines
7.1 KiB
Markdown
152 lines
7.1 KiB
Markdown
# 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++ 库、历史接口、跨语言互操作代码等。
|