Rust:无法将 `Iterator<Item = Box<Dog>>` 收集到 `Vec<Box<dyn Animal>>` 中

A. *_*man 3 rust trait-objects

我觉得这段代码应该可以工作,因为在大多数情况下Box<Dog>s 应该能够隐式转换为s:Box<dyn Animal>

struct Dog {}
trait Animal {}
impl Animal for Dog {}

fn main() {
    let _: Vec<Box<dyn Animal>> = [Dog {}, Dog {}]
        .into_iter()
        .map(Box::new)
        .collect();
}
Run Code Online (Sandbox Code Playgroud)

但是,我收到以下编译器错误:

error[E0277]: a value of type `Vec<Box<dyn Animal>>` cannot be built from an iterator over elements of type `Box<Dog>`
    --> src/main.rs:9:10
     |
9    |         .collect();
     |          ^^^^^^^ value of type `Vec<Box<dyn Animal>>` cannot be built from `std::iter::Iterator<Item=Box<Dog>>`
     |
     = help: the trait `FromIterator<Box<Dog>>` is not implemented for `Vec<Box<dyn Animal>>`
     = help: the trait `FromIterator<T>` is implemented for `Vec<T>`
note: required by a bound in `collect`

For more information about this error, try `rustc --explain E0277`.
Run Code Online (Sandbox Code Playgroud)

我还尝试插入 a.map(Into::into)Box<Dog>s 转换为Box<dyn Animal>s ,但这给出了错误the trait bound `Box<dyn Animal>: From<Box<Dog>>` is not satisfied

那么我该如何将我的Box<Dog>s 收集到Box<dyn Animal>s 中呢?

Cha*_*man 5

你快到了。问题在于Box::new()索取T和给予Box<T>。任何强制都是不可能的。

相反,您应该提供一个闭包|v| Box::new(v),但即使这样还不够,因为编译器不会立即意识到它需要强制,而当它意识到时就为时已晚(您可以在此处阅读更多内容)。你需要提示一下。一个简单的as就足够了:|v| Box::new(v) as _.