This code give me a compilation error:
trait IBoo {
fn new() -> Box<IBoo>;
}
while this code compiles without any error:
trait IBoo {
//fn new() -> Box<IBoo>;
}
trait IFoo {
fn new() -> Box<IBoo>;
}
- Why does the first one not compile?
rustc --explain E0038
does not give me a direct hint why it is not possible. - Is it possible to combine construction and methods in one interface (trait)?
The compiler tells you the exact reason this doesn't work:
Note the last line. It's telling you that the reason for the error is that
new()
doesn't depend on having an instance of a value implementing theIBoo
trait.By not taking a pointer of some kind to
self
, the method cannot be invoked by dynamic dispatch. If it can't be invoked by dynamic dispatch, this means it cannot go into the trait's associated vtable. There has to be an associated vtable, because that's how something likeBox<IBoo>
works. Some time ago, the core Rust developers decided that including even a single "non-object safe" method in a trait disqualified the whole trait from being used as an object.To put it in other words: because you've defined a method that cannot be dynamically dispatched, the
IBoo
trait as a whole is disqualified from being used with dynamic dispatch.If you want some kind of constructor function, you need to have some other way of writing that. This could be using plain function pointers, or an
IBooFactory
trait, as you might with Java.This is from the description of E0038:
You can do this:
In other cases, you can place the restriction on the entire impl: