Is there a way to make this work?
pub trait Foo {
fn new() -> T { T { ..Default::default()} }
}
where T would be some struct.
this fails to compile with "error: T
does not name a structure".
Is there a way to make this work?
pub trait Foo {
fn new() -> T { T { ..Default::default()} }
}
where T would be some struct.
this fails to compile with "error: T
does not name a structure".
I do not think you can do that with traits. A similar approach (but not a factory new() method) is to use Self. However, it does not look like you can make a default method for this in the trait because "Self" does not have a known size at compile time. The best you could do is to force its implementation on structs.
trait MyTrait {
fn new() -> Self;
}
Also, to solve your issue, you could create a factory method, but I am not sure if this really does any more for you than calling MyStruct::new().
fn new<T>() -> T where T: Default {
Default::default()
}
See this code for more details.
Hope that helps.
Your problem here is T
is not a concrete type, but a type parameter, which can be pretty much anything, e.g. an enum, a struct, a trait object, whatever. So you just can't instantiate something unknown as if it were a struct.
@wspowell already gave you working code, so I won't repeat it. A possible variant can be:
trait MyTrait: Default {
fn new() -> Self {
Default::default()
}
}
which is really doesn't have much sense by itself, as you can just as well use Default::default()
directly, unless you put some more complex logic in your new()
method.
I think it should be
fn new() -> Self where Self: Sized
because by default Self
in a trait has ?Sized
bound and so it can't be returned from a function.