Reputation: 612
trait MyTrait {
fn my_f(&self) ;
}
struct A {}
struct B {}
impl MyTrait for A {
fn my_f(&self) {
println!("A.my_f()");
}
}
impl MyTrait for B {
fn my_f(&self) {
println!("B.my_f()");
}
}
struct MyList<T: MyTrait> {
list: Vec<T>
}
fn main() {
let list = MyList {
list: vec![
Box::new(A{}),
Box::new(B{})
]
};
}
I followed this article, Using Trait Objects That Allow for Values of Different Types
According to this article:
This restricts us to a Screen instance that has a list of components all of type Button or all of type TextField. If you’ll only ever have homogeneous collections, using generics and trait bounds is preferable because the definitions will be monomorphized at compile time to use the concrete types.
On the other hand, with the method using trait objects, one Screen instance can hold a Vec that contains a Box as well as a Box. Let’s look at how this works, and then we’ll talk about the runtime performance implications.
But this code can't be compiled.
Upvotes: 3
Views: 828
Reputation: 23244
Read more closely the section on Defining a Trait for Common Behavior. It defines Screen
in listing 17-4 with a Vec<Box<dyn Draw>>
:
pub struct Screen {
pub components: Vec<Box<dyn Draw>>,
}
Then it says:
we could have defined the
Screen
struct using a generic type and a trait bound as in Listing 17-6
Emphasis on the conditional "could". It then goes on to explain why using a generic type and trait bound doesn't work:
This (1) restricts us to a
Screen
instance that has a list of components all of typeButton
or all of typeTextField
.[…]
On the other hand, with the method using trait objects (2), one
Screen
instance can hold aVec<T>
that contains aBox<Button>
as well as aBox<TextField>
.
(1) using a generic type and trait bound
(2) i.e. with Box<dyn<Draw>>
Upvotes: 3