Reputation: 11831
I'm still very new to Rust and am trying to get my head around the differences between Java interfaces and Rust traits. The example below is trying to model the way I'd do things in Java, which may not be the idiomatic way in Rust.
I have a trait where I would like to return some implementation of the trait/interface by calling a from_str()
method:
pub trait Ast: Display + Debug {
fn from_str(dot_str: &str) -> Result<Box<Self>, AstParseError>;
// some other methods applicable to Ast
}
Now here is an implementation of the trait (assume struct AstParseError
exists):
pub struct DotAst {}
impl Ast for DotAst {
fn from_str(str: &str) -> Result<Box<dyn Ast>, AstParseError> {
// ...
// now return a boxed version of my Ast implementation
Ok(Box::new(DotAst::new()))
}
}
I get an error "the trait Ast
cannot be made into an object E0038". What should the signature of my DotAst from_string()
implementation look like? Is this even possible in Rust, or should I be following a different pattern entirely. The motivation is that I want to have many types of Ast, where I'd like to call from_str()
on a specific implementation and receive the generic object back.
Upvotes: 0
Views: 293
Reputation: 1400
Looks like you just need to append where Self: Sized
to the method declaration to make the function "explicitly non-dispatchable": https://doc.rust-lang.org/reference/items/traits.html#object-safety.
pub trait Ast: Debug + Display {
fn from_str(dot_str: &str) -> Result<Box<dyn Ast>, AstParseError> where Self: Sized;
}
Upvotes: 1