I would like to write a function that parses a string and returns one of several structs that implement a trait object that allows handing out references to the implementing struct. The use case is reading a string from a configuration file that determines which implementation is used. The code looks like this:
trait Foo<'a> {
fn get(&'a self) -> &'a i32;
}
struct Bar {
data: i32,
}
impl<'a> Foo<'a> for Bar {
fn get(&'a self) -> &'a i32 {
&self.data
}
}
struct Baz {
data: i32,
}
impl<'a> Foo<'a> for Baz {
fn get(&'a self) -> &'a i32 {
&self.data
}
}
fn get_foo(foo: &str) -> Box<dyn Foo> {
let split = foo.splitn(2, "+").collect::<Vec<_>>();
let data = i32::from_str_radix(split[1], 10).unwrap();
if foo.starts_with("bar") {
Box::new(Bar { data })
} else {
Box::new(Baz { data })
}
}
fn main() {
let foo = get_foo("bar+0");
println!("Foo: {}", foo.get());
}
However, when I do that, I get this error:
error[E0597]: `*foo` does not live long enough
--> src/main.rs:38:25
|
38 | println!("Foo: {}", foo.get());
| ^^^ borrowed value does not live long enough
39 | }
| - `*foo` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
Is this possible to do in Rust?