polymorphism - Vector of objects belonging to a trait -
consider following code:
trait animal { fn make_sound(&self) -> string; } struct cat; impl animal cat { fn make_sound(&self) -> string { "meow".to_string() } } struct dog; impl animal dog { fn make_sound(&self) -> string { "woof".to_string() } } fn main () { let dog: dog = dog; let cat: cat = cat; let v: vec<animal> = vec::new(); v.push(cat); v.push(dog); animal in v.iter() { println!("{}", animal.make_sound()); } } the compiler tells me v vector of animal when try push cat (type mismatch)
so, how can make vector of objects belonging trait , calls corresponding trait method on each element?
vec<animal> not legal, compiler can't tell because type mismatch somehow hides it. if remove calls push, compiler gives following error:
<anon>:22:9: 22:40 error: instantiating type parameter incompatible type `animal`, not fulfill `sized` [e0144] <anon>:22 let mut v: vec<animal> = vec::new(); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ the reason why that's not legal vec<t> stores many t objects consecutively in memory. however, animal trait, , traits have no size (a cat , dog not guaranteed have same size).
to solve problem, need store has size in vec. straightforward solution wrap values in box, i.e. vec<box<animal>>. box<t> has fixed size (a "fat pointer" if t trait, simple pointer otherwise).
here's working main:
fn main () { let dog: dog = dog; let cat: cat = cat; let mut v: vec<box<animal>> = vec::new(); v.push(box::new(cat)); v.push(box::new(dog)); animal in v.iter() { println!("{}", animal.make_sound()); } }
Comments
Post a Comment