Zhou Lebo
Zhou Lebo

Reputation: 41

Error E0277 following book example dyn Trait, how to push a dyn trait in vector?

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

Answers (1)

cafce25
cafce25

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

Related Questions