Rust能否从实现Trait的迭代器收集得到Vec<&dyn Trait>?
Rust 完全支持从实现了目标 trait 的类型的引用迭代器收集得到 Vec<&dyn Trait> 类型的容器,你遇到的报错是类型推导阶段没有触发隐式类型转换导致的。
两种写法的差异原因
- 单独
push的场景:你已经明确声明了Vec的元素类型是&dyn Animal,编译器在处理push(&dog1)的参数时,会自动将具体类型&Dog做DST 隐式转换,转成 trait 对象胖指针&dyn Animal,所以可以正常运行。 - 迭代器
collect的场景:dogs.iter()生成的迭代器元素类型固定为&Dog,collect方法的类型推导逻辑是优先匹配迭代器元素类型对应的FromIterator实现,这个过程不会自动为每个元素执行隐式的 DST 转换,因此找不到匹配的FromIterator<&Dog> for Vec<&dyn Animal>实现,触发编译错误。
正确实现方法
只需要在迭代过程中显式为每个元素做类型转换,告知编译器要将具体类型引用转为 trait 对象即可,修改后的代码如下:
trait Animal { fn make_sound(&self) -> String; } struct Dog; impl Animal for Dog { fn make_sound(&self) -> String { "woof".to_string() } } fn main() { let dogs = [Dog, Dog]; // 显式转换每个元素为 &dyn Animal 后再收集 let v: Vec<&dyn Animal> = dogs.iter().map(|dog| dog as &dyn Animal).collect(); for animal in v.iter() { println!("{}", animal.make_sound()); } }
上述代码可以正常编译运行,输出两次woof。
内容的提问来源于stack exchange,提问作者Florian sp1rit
相关产品推荐
相关产品推荐

