Rust能否定义包含返回trait对象泛型函数的trait
Rust 泛型Trait返回Trait对象问题解答
核心问题答复
问题1:泛型参数是否可以为trait对象类型?
可以。trait对象是Rust中的合法类型,完全可以作为泛型参数传入使用。你给出的示例代码存在语法错误:dyn关键字后必须跟具体的trait名称,不能直接跟泛型参数T,因此&dyn T的写法不合法。
问题2:是否可以定义包含泛型函数的trait,且该泛型函数能够返回任意trait对象?
可以实现,只需要调整泛型约束和写法即可,修正后的可运行示例如下:
// 泛型参数T添加?Sized约束,允许接收动态大小的trait对象类型 trait ToVec<T: ?Sized> { // 当T为trait对象类型时,&T自动等价于&dyn 对应trait fn to_vec(&self) -> Vec<&T>; } trait TraitA {} trait TraitB {} // 示例结构体,同时实现TraitA和TraitB struct MyStruct; impl TraitA for MyStruct {} impl TraitB for MyStruct {} // 为MyStruct实现返回TraitA trait对象的版本 impl ToVec<dyn TraitA> for MyStruct { fn to_vec(&self) -> Vec<&dyn TraitA> { vec![self] } } // 为MyStruct实现返回TraitB trait对象的版本 impl ToVec<dyn TraitB> for MyStruct { fn to_vec(&self) -> Vec<&dyn TraitB> { vec![self] } } fn main() { let s = MyStruct; // 可根据调用上下文返回对应类型的trait对象列表 let vec_a: Vec<&dyn TraitA> = s.to_vec(); let vec_b: Vec<&dyn TraitB> = s.to_vec(); }
关键注意点
- Rust泛型参数默认要求是编译期可确定大小的类型,而trait对象是动态大小类型(DST),因此必须给泛型参数添加
?Sized约束才能接收trait对象作为泛型实参。 - 当你将
dyn TraitA这类trait对象作为实参传给泛型参数T时,返回值中的&T就自动对应&dyn TraitA类型的trait对象引用,完全符合需求。 - 如果需要返回任意自定义trait的对象,只需要为对应trait的
ToVec<dyn 自定义trait>添加实现即可。
内容的提问来源于stack exchange,提问作者zino
相关产品推荐
相关产品推荐

