> However, the extensibility of trait objects comes at the cost of fat > pointers, which can be a problem if you have a lot of pointers.
This is fixable without introducing virtual functions, by adding a way to express "Struct and vtable for impl Trait for Struct" and "thin pointer to Struct and vtable for impl Trait for Struct" (or by using an indirect pointer, i.e. ~~Trait or Rc<~Trait>). > It also implies that downcasting isn't really possible, at least not > cheaply, because there is no notion of the "actual type" of a > particular object. I don't understand this. You can downcast trait pointers to struct pointers just fine, since you can put whatever information needed in the trait impl vtable (such as a typeid). Sure, you can't "downcast" a struct to a struct, but that's the whole point of structs. The idea of a struct is that one is referring to something of EXACTLY that type, and so downcasting makes no sense; when one wants a "variable" type one uses a trait and then you can (attempt to) downcast to concrete structs. One can of course introduce "virtual struct"s which are no longer exactly of that type but are now virtual, but that just overlaps the role of traits. > (As an aside, I am personally happier to see virtual structs than to> see > traits extending structs or traits extending a `HasPrefix` trait,> as was > included in previous designs. Both of those approaches mean> that the trait > is no longer "pure interface", and if you write> "generic" code against that > trait, you're actually coding at least> partially against a fixed > implementation, not an interface.) I think traits inheriting structs is a better design, because you can have multiple traits inheriting the same struct. For example, let's say you are modelling GUI widgets which need both input handling and drawing support. With traits inheriting structs, you can have several traits, one for input handling, one for drawing in memory, one for drawing with OpenGL, etc., while with virtual functions (and without multiple inheritance) you have to put everything together and you have to either implement all functionality or add "not supported" error codes. In other words, a trait inheriting a struct neatly separates the trait part where multiple inheritance is natural from the struct part where single inheritance is natural. Also, a trait inheriting a Struct behaves to users of the trait exactly like a trait with a get_struct() accessor method, but with better performance. It's only different for implementors, where it mandates how get_struct() is implemented for the sake of performance, at the cost of making it impossible to implement it along with traits inheriting from incompatible structs. In general I think it's better to have multiple options at a low level like this, rather than having multiple option at an high-level semantic level like virtual struct vs trait, since that exposes the choice less to other modules. _______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev