在编程设计中对 分类、类型、状态 进行设计时,很多时候选择的单词本身并不能体现现分类、类型的含义,比如:Error、Message,那这时我们就会加上 Type 后缀,对应的字段通知就会使用 type 进行命名。比如在定义消息体时:
1 | pub struct MessagePayload { |
但是,type 在 Rust 中是关键字,这里将字段命名为 type 是不合法的,可以改为 msg_type。那有其它可替代 type 的单词吗(假定我们在编程中通常使用英语单词进行命名),那就是 kind。后续本文将较为详细的讨论在编程设计中什么时候使用 Type,而又在什么时候合适使用 Kind。
英语语言分析:kind vs type
核心语义差异
| 维度 | kind | type |
|---|---|---|
| 本质 | 自然属性/内在分类 | 技术规格/系统分类 |
| 来源 | 自然形成/本质特征 | 人为定义/技术标准 |
| 范围 | 宽泛类别 (what sort of) | 精确类型 (what specific) |
| 示例 | “What kind of fruit?” | “What type of file?” |
| 适用域 | 生物/行为/抽象概念 | 技术/系统/协议规范 |
编程场景适用原则
适合用 Kind 的场景:
- 自然属性分类:错误类型、用户状态、生物类别
- 行为特征:操作类型、事件类别
- 本质差异:编译器标记、语法元素
- 宽泛分类:需要后续细分的顶层类别
适合用 Type 的场景:
- 技术规范:协议格式、硬件类型
- 系统标准:文件格式、数据类型
- 精确规格:消息协议、API 版本
- 人为定义:业务逻辑中的分类标准
📌 核心经验法则:
当分类反映 内在本质 时用Kind,反映 技术规范 时用Type
编程语言实现方案
Rust 最佳实践
1 | // 不加场景(`Status` 状态已隐含分类的含义) |
TypeScript 最佳实践
1 | // 不加场景(`Status` 状态已隐含分类的含义) |
使用 serde 自定义序列化时的名称
在 Rust 中可以使用 serde 和 serde_json 将 ty 字段序列化为 type 字段。示例代码如下:
1 | use serde::{Serialize, Deserialize}; |
关键解决方案说明
#[serde(rename = "type")]属性- 将结构体字段 ty 序列化为 JSON 的 type 字段
- 反序列化时自动将 JSON 的 type 映射回 ty 字段
字段命名策略
1
2
3
4
5
6
7
8
9
10
11// 推荐方案:
struct NetworkMessage {
ty: MessageType, // 清晰且避免关键字
}
// 替代方案(不推荐):
struct NetworkMessage {
r#type: MessageType, // 使用原始标识符语法,可读性差
}枚举序列化优化
1
2
3
4
5
6
7
8// 默认使用变体名(如 "Text")
enum MessageType { Text, Image }
// 可选:序列化为小写蛇形命名
enum MessageType { Text, Image } // 变为 "text", "image"
Typescript 对比
在 typescript 中,可以使用 type 作为类型的字段命名。
1 | // 类型定义 |
使用场景小结
| 场景 | Rust 方案 | TypeScript 方案 |
|---|---|---|
| 技术规格分类 | #[serde(rename = "type")] ty: T |
直接使用 type: T |
| 本质属性分类 | 直接使用 kind: ErrorKind |
直接使用 kind: ErrorKind |
| 规避关键字 | ty + rename 属性 |
无需特殊处理 |
| 枚举序列化 | #[serde(rename_all = "...")] |
原生支持字符串枚举 |
最佳实践建议:
- 对技术规格类字段使用 ty + #[serde(rename = “type”)]
- 对本质属性类字段直接使用 kind
- 始终在 JSON 层保持语义正确的字段名(如 type)
- 在代码层使用非关键字字段名(如 ty)确保编译通过
总结: 跨语言通用准则
优先使用 Kind 的情况
- 状态/错误分类:
UserStatusKind,ErrorKind - 自然属性:
AnimalKind,MaterialKind - 行为模式:
InteractionKind,EventKind - 编译器内部:
TokenKind,NodeKind
优先使用 Type 的情况
- 协议/格式:
MsgType,FileType - 硬件规范:
DeviceType,CpuType - 数据传输:
PayloadType,EncodingType - 业务标准:
InvoiceType,PaymentType
关键字处理策略
| 语言 | 推荐方案 | 备选方案 |
|---|---|---|
| Rust | msg_type/record_type |
ty/kind |
| TypeScript | msgType/contentType |
kind/variant |
| Go | msgType/contentType |
kind/cat |
💡 黄金法则:
当不确定时,选择Kind更安全(80%场景适用),
仅在明确技术规范时使用Type(需处理关键字问题)