泛型设计
什么条件下值得使用泛型,什么条件下应保持普通函数?
-
容器结构: stack, set, queue 等持有任意元素类型的数据结构;
-
算法复用: 对多种数值类型执行相同逻辑;
-
类型安全: 避免使用
any后再做类型断言; -
单一类型逻辑: 直接写普通函数更清晰;
-
约束复杂: 需要大量类型分支时泛型收益较低;
-
业务抽象: 优先使用具体类型和接口表达行为;
接口与泛型有何区别? 何时优先用哪一种?
| 机制 | 关注点 |
|---|---|
| interface | 值能做什么行为 |
| generic | 代码能适配哪些类型 |
- 接口优先: 调用方只关心对象能做什么时,用 interface 表达行为;
- 泛型优先: 算法需要保留具体类型,或多个输入与输出必须保持同一类型关系时,用类型参数;
- 组合使用: 泛型约束本身由 interface 表达,两者不是互斥方案;
- 判断问题: 若删除类型参数后只能改用
any和类型断言,并且所有类型执行相同算法,泛型通常有价值;
// 行为抽象:调用方只关心能否写入字节。
func WriteMessage(w io.Writer, message string) error {
_, err := io.WriteString(w, message)
return err
}
// 类型关系:输入和输出保持同一个具体类型。
func Keep[T any](v T) T { return v }
- 示例前提: WriteMessage 需要导入标准库
io;这里比较两种抽象承担的责任,而不是要求把它们组合成同一个 API;