关于 rust-trait-api-design
面向 Rust 开发者的 Trait API 设计技能,帮助选择具体类型、泛型或 Trait 对象,并指导约束、转换、对象安全性及 API 测试。
主要功能
- 01选择具体类型、泛型或动态分发
- 02将约束放在需要的位置
- 03设计下游实现边界
- 04采用标准转换 Trait
- 05检查 Trait 对象安全性
- 06测试公开 API 的使用方式
适用场景
- 01设计公开的 Rust Trait API
- 02选择泛型或 dyn Trait
- 03审查转换实现
- 04测试下游用户的 API 调用方式
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ lvtd-llc/ skills --skill rust-trait-api-design安装后在 Claude Code 中输入/rust-trait-api-design确认已加载。
附带文件agents/openai.yamlreferences/trait-api-patterns.md
详细介绍
Rust Trait API 设计
使用此技能,在适用时让 Rust API 支持泛型,在更简单时使用具体类型,并在设计包含动态分派时确保对象安全。将能力契约精简到调用方和实现者都能理解的最小范围。
核心工作流
- 确定 API 是消费、借用、返回、存储还是分派行为。
- 本地代码从具体类型开始。仅当至少两个调用方或实现需要灵活性时,才泛化。
- 使用泛型约束实现编译期多态和内联。使用
dyn Trait实现异构值、类似插件的扩展点或运行时分派。 - 将约束放在需要它们的位置。约束较长或涉及关联类型时,优先使用
where子句。 - 确定此 trait 是否旨在供下游实现。若不变量不得由外部实现,请封闭该 trait、将字段设为私有,或使用构造函数。
- 标准转换 trait 完全适用时,优先使用它们。在检查
From、TryFrom、AsRef、AsMut、Borrow、ToOwned和Cow之前,不要自创转换 trait。 - 添加编译测试、单元测试或示例,证明公共 API 可以按此技能预期的方式供未来用户调用。
API 设计规则
- 如果调用方应能传入多种具体类型,请为参数接受
impl Trait或命名泛型。 - 隐藏一种具体返回类型时,返回
impl Trait。如果具体类型在运行时会变化,则返回Box<dyn Trait>。 - 如果每个实现都有一种自然关联类型,优先使用关联类型。如果一个实现支持多种目标类型,优先使用泛型 trait 参数。
- 对无损转换实现
From,对可能失败的转换实现TryFrom。实现这些 trait 后,调用方即可使用Into和TryInto。 - 使用
AsRef进行开销低的引用到引用转换。仅当借用形式和拥有形式的Eq、Hash和Ord行为等价时,才使用Borrow。 - 除非算法在语义上需要按位复制,否则避免添加
Copy约束。
Trait 对象审查
在选择泛型还是 dyn Trait 时,或公共 trait 未通过对象安全检查时,请阅读 references/trait-api-patterns.md。
在让公共 trait 支持对象安全之前,请检查:
- 方法不使用泛型类型参数。
- 方法不返回
Self,除非受到where Self: Sized约束。 - 必要时,在 trait 对象上指定关联类型。
- 对象置于指针后,例如
&dyn Trait、Box<dyn Trait>或Arc<dyn Trait + Send + Sync>。
常见异味
- 公共函数接受
&Vec<T>,但实际只需要迭代。 - API 接受
String,随后立即将其借用为&str。 - API 直接实现
Into,而非From。 - trait 包含许多实际上只有一个方法需要的宽泛约束。
- 使用 trait 对象只是因为生命周期令人困惑,而不是因为确实需要运行时分派。
- 在公共 trait 中使用
async-trait,却未检查 trait 中的原生async fn、trait-variant或装箱 future 是否更适合分派和Send需求。
评论
支持 Markdown