I am currently trying to refactor some of my rust code and have run into a problem which seems to be occurring far more often than I would like to admit. Let's start with the code and than the explanation:
trait Foo {
fn fizz(&self) {}
}
struct FooBar {}
impl Foo for FooBar {}
struct Bar {}
impl Foo for Bar {}
fn foo_bar() -> Result<FooBar, ()> {
Ok(FooBar{})
}
fn create_fizz_buzz(id: String) {
let fizz_buzz: &Foo;
if id == "bar" {
// Does not work
fizz_buzz = match &foo_bar() {
Ok(new_instance) => new_instance,
Err(_) => panic!("Ahhh"),
};
// This would work but then you can't use a factory function which could fail.
// fizz_buzz = &FooBar{};
} else {
fizz_buzz = &Bar{};
}
// Do some work with fizz_buzz.
}
fn main() {
create_fizz_buzz("bar".to_string());
}
I am trying to create a object dynamically based on an identifier given to a function. Since all objects which could be created implement the same trait
I can just create a match
on the identifier. In this match
I create the object and then assign it to a reference which expects the trait. Now I can use the reference to call functions on the reference. Sounds good.
However, once you try to use a factory function which can fail to create the objects, you can not assign the unpacked the objects to the reference variable due to their lifetime. (If you need to handle possible errors.) It compiles with the error
error[E0597]: borrowed value does not live long enough
--> src/main.rs:20:28
|
20 | fizz_buzz = match &foo_bar() {
| ^^^^^^^^^ temporary value does not live long enough
...
23 | };
| - temporary value dropped here while still borrowed
...
32 | }
| - temporary value needs to live until here
|
= note: consider using a `let` binding to increase its lifetime
Is there a way to do this correctly in Rust?
(I can do this in other programming languages, I mean, I am just trying to set a reference in a switch
statement right? [Same problem applies to if
s by the way.])