rust - Encompassing Trait Objects within a Base Trait Object -


sorry if seems trivial, i'm trying simple operation having tough time doing so. want have 2 trait objects whereby 1 has vector contains bunch of other object.

trait metaclass {     fn new() -> self;     fn add(&self, subtrait: box<subclass>); }  struct metastruct {     elems: vec<box<subclass>>, }  impl metaclass metastruct{     fn new() -> metastruct {         metastruct{             elems: vec::new(),         }     }      fn add(&self, subtrait: box<subclass>){         // if reformulate above 'fn add(&self, subtrait: subclass){'         // , use below trait `core::marker::sized` not implemented type `subclass`         //self.elems.push(box::new(subtrait));         self.elems.push(subtrait);     } }   trait subclass{     fn new() -> self; }  struct mysubclass {     data: i32, }  impl subclass mysubclass {     fn new() -> mysubclass{         mysubclass{             data: 10,         }     } }   fn main(){     let mut meta = box::new(metastruct::new());     // ideally want meta.add(mysubclass::new()) mentioned above has sizing issues :'(     meta.add(box::new(mysubclass::new())); } 

the error getting is:

<anon>:45:11: 45:38 error: cannot convert trait object because trait `subclass` not object-safe [e0038] <anon>:45   meta.add(box::new(mysubclass::new()));                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~ 

here link rust play: http://is.gd/pjlhej

i have tried following, got same error:

meta.add(box::new(mysubclass::new()) box<subclass>); 

ideally if there way rust's static dispatch ideal, okay dynamic dispatching well. in each case think make sense have metaclass own object of subclass, don't want pass reference it, entire object itself.

i want have 2 trait objects whereby 1 has vector contains bunch of other object.

that's straight-forward enough:

trait traitone {     fn add(&mut self, another: box<traittwo>); }  trait traittwo {     fn value(&self) -> u8;  }  struct container(vec<box<traittwo>>); impl traitone container {     fn add(&mut self, another: box<traittwo>) {         self.0.push(another);     } }  struct thingone(u8); impl traittwo thingone {     fn value(&self) -> u8 { self.0 } }  struct thingtwo(u8, u8); impl traittwo thingtwo {     fn value(&self) -> u8 { self.0 + self.1 } }  fn main() {     let mut trait_1: box<traitone> = box::new(container(vec![]));      let thing_1: box<traittwo> = box::new(thingone(42));     let thing_2: box<traittwo> = box::new(thingtwo(21, 21));      trait_1.add(thing_1);     trait_1.add(thing_2); } 

your real error object safety. huon wilson (a rust core team member) wrote great blog post this.

in case have trait:

trait subclass{     fn new() -> self; } 

this not object safe, quoting huon (emphasis mine):

there’s 2 fundamental ways in can happen, argument or return value, in either case reference self type means must match type of self value, true type of unknown @ compile time.

that is, how many bytes need allocated on stack or heap hold object returned fn new() -> self? cannot know, because have trait object.

one solution make sure self sized in trait, per followup blog post:

trait subclass {     fn new() -> self self: sized; } 

then, fix mutability mismatches in trait, , compiles.


Comments

Popular posts from this blog

javascript - Karma not able to start PhantomJS on Windows - Error: spawn UNKNOWN -

Nuget pack csproj using nuspec -

c# - Display ASPX Popup control in RowDeleteing Event (ASPX Gridview) -