@dylan.dpc - You chose an excellent title that makes it easy for others stuck on the same problem to find help. It helped me at least I apologize if you were surprised by the notification, and totally get how that can be an unexpected annoyance - but imho it's better to collect the knowledge on this topic here rather than start another post with nearly the same exact question - and it turns out that the state of the art here has not changed that much in a year. At the same time, for sure it's a subjective preference... I get it.
Fwiw I tried tinkering around with impl Trait
returns and, as explained by everyone above, couldn't make it work. Dynamic dispatch it is! Here's a working example:
(outputs both "foo" and "bar")
use std::fmt::{Display, Formatter, Result};
struct Foo {}
struct Bar {}
impl Display for Foo {
fn fmt(&self, f: &mut Formatter) -> Result {
write!(f, "foo")
}
}
impl Display for Bar {
fn fmt(&self, f: &mut Formatter) -> Result {
write!(f, "bar")
}
}
fn get_something (name:&str) -> Option<Box<dyn Display>> {
match name {
"foo" => Some(Box::new(Foo{})),
"bar" => Some(Box::new(Bar{})),
_ => None
}
}
fn main() {
println!("{}", get_something("foo").unwrap());
println!("{}", get_something("bar").unwrap());
}