Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I populate a vector of trait objects using an array?

Tags:

rust

Why is the following code an error? There is a blanket implementation for [T; N] into Vec<T>, so why does dyn Foo not match Fooable in this context? Is there a workaround which does not involve cloning the Fooable?

trait Foo {}

struct Fooable {}

impl Foo for Fooable {}

pub fn main() {
    let bar: Vec<Box<dyn Foo>> = [
        Box::new(Fooable {}),
    ].into();
}

Error:

error[E0277]: the trait bound `Vec<Box<dyn Foo>>: From<[Box<Fooable>; 1]>` is not satisfied
  --> src/main.rs:10:7
   |
10 |     ].into();
   |       ^^^^ the trait `From<[Box<Fooable>; 1]>` is not implemented for `Vec<Box<dyn Foo>>`
   |
   = help: the following other types implement trait `From<T>`:
             <Vec<T, A> as From<Box<[T], A>>>
             <Vec<T, A> as From<VecDeque<T, A>>>
             <Vec<T> as From<&[T]>>
             <Vec<T> as From<&mut [T]>>
             <Vec<T> as From<BinaryHeap<T>>>
             <Vec<T> as From<Cow<'a, [T]>>>
             <Vec<T> as From<[T; N]>>
             <Vec<u8> as From<&str>>
           and 2 others
   = note: required because of the requirements on the impl of `Into<Vec<Box<dyn Foo>>>` for `[Box<Fooable>; 1]`

Playground

like image 268
frankplow Avatar asked Apr 18 '26 07:04

frankplow


1 Answers

You're right. There's a blanket implementation for From<[T; n]> on Vec<T>. That means you can convert [T; n] into Vec<T> with From::from or Into::into.

More specifically, that means you can convert a [Box<Fooable>; 1] into a Vec<Box<Fooable>>, or a [Box<dyn Foo>; 1] into a Vec<Box<dyn Foo>>. However, you have a [Box<Fooable>; 1] and want a Vec<Box<dyn Foo>>, and since the T is different, the blanket impl doesn't apply.

Use an explicit cast to get the behavior you want. You just have to convince Rust that the type of the array is [Box<dyn Foo>; 1], not [Box<Fooable>; 1] as it originally infers.

let bar: Vec<Box<dyn Foo>> = [
    Box::new(Fooable {}) as Box<dyn Foo>,
].into();
like image 149
Silvio Mayolo Avatar answered Apr 21 '26 12:04

Silvio Mayolo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!