在编程设计中对 分类、类型、状态 进行设计时,很多时候选择的单词本身并不能体现现分类、类型的含义,比如: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
(需处理关键字问题)