Reputation: 41
My real case is similar to the Rust doc about dyn trait with Screen and Draw trait.
So I built an example totally similar to the book. But instead of initializing the vector in place, I need to have a register function to push components into the vector. But I get error: the trait Sized
is not implemented for dyn Draw
I don't understand how to fix it...
pub trait Draw {
fn draw(&self);
}
pub struct Screen {
pub components: Vec<Box<dyn Draw>>,
}
impl Screen {
fn new() -> Self {
Screen {
components: Vec::new(),
}
}
fn register(&mut self, w: &dyn Draw) {
self.components.push(Box::new(*w));
}
fn show(&self) {
for d in self.components {
d.draw()
}
}
}
struct TextBox {
txt: String,
}
impl TextBox {
fn new(t: &str) -> Self {
TextBox { txt: t.to_string() }
}
}
struct Button {
label: String,
}
impl Button {
fn new(l: &str) -> Self {
Button {
label: l.to_string(),
}
}
}
impl Draw for TextBox {
fn draw(&self) {
println!("{}", self.txt.as_str())
}
}
impl Draw for Button {
fn draw(&self) {
println!("{}", self.label.as_str())
}
}
fn main() {
let s = Screen::new();
let b = Button::new("Button1");
let t = TextBox::new("Some text");
s.register(&b as &dyn Draw);
s.register(&t as &dyn Draw);
s.show();
}
Upvotes: 2
Views: 114
Reputation: 27546
You can't dereference a &dyn Trait
because that would create something of unknown size on the stack.
Instead you can take impl Trait
and box it up or take Box<dyn Draw>
directly:
fn register(&mut self, w: impl Draw + 'static) {
self.components.push(Box::new(w));
}
and pass in the objects themselves instead of references to them:
let b = Button::new("Button1");
let t = TextBox::new("Some text");
s.register(b);
s.register(t);
Note: the + 'static
means that w
can't contain any references shorter than 'static
it does not mean that w
has to live forever.
Upvotes: 2