Reputation: 13450
#[derive(Default)]
struct Bar;
#[derive(Default)]
struct Baz;
fn main() {
let mut vec = Vec::<Box<dyn Default>>::new();
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::default::Default` cannot be made into an object
vec.push(Box::new(Bar));
vec.push(Box::new(Baz));
}
Default is a sized Trait, which means you cannot convert it to a trait object.
For the example above, is there a workaround so I can store sized traits in a Vec
(or any other collection)?
Upvotes: 3
Views: 133
Reputation: 42859
You cannot do such a thing because of the object safety rule. This rule says that a trait which a method returns the concrete type itself cannot be made into a trait object. The reason is that the trait object would have known the concrete type.
Also, this trait has no method (a function that takes self
), so there is no point to make a trait object from it.
See more about this rule here, there and in this blog article.
See also this question.
This rule is pretty intuitive: what do you expect your code to do?
#[derive(Default)]
struct Bar;
#[derive(Default)]
struct Baz;
fn main() {
let mut vec = Vec::<Box<dyn Default>>::new();
vec.push(Box::new(Bar));
vec.push(Box::new(Baz));
vec.first().unwrap()::new();
// Whatever the syntax should be, what do you expect this to return?
// This type cannot be know at compile time.
}
Upvotes: 5