Rust Trait Object 边界:动态分发要有明确理由
背景 静态泛型可以保留具体类型,trait object 可以把实现选择推迟到运行时。选哪一种,应先看模块边界是否真的需要动态替换。 核心判断 同构热点内部优先清晰的泛型接口,异构集合或插件边界考虑 dyn Trait。 跨线程接口按实际需要约束 Send 与 Sync。 控制 trait 的职责与方法签名,让公共边界可测试、可演进。 最小示例 下面保留核心逻辑;业务类型、调用入口和环境配置按项目补齐。 trait Storage: Send + Sync { fn get(&self, key: &str) -> Result<Vec<u8>, Error>; } fn read(store: &dyn Storage, key: &str) -> Result<Vec<u8>, Error> { store.get(key) } 边界与误区 并非所有 trait 都能成为 trait object;带某些泛型方法或返回 Self 的接口需要重新设计。示例只展示同步边界,Error 属于业务定义。 验证方式 实现内存与远程两种 Storage,验证调用方无需改动;在真实负载下测分派成本,不凭动态调用次数推断整体性能。 小结 内部高频路径优先静态分发,插件和依赖注入边界再使用 trait object。