How to return the reference to the struct / object assigned locally? AKA error: `foo` does not live long enough

advertisements

Here's a simplified example of what I'm doing:

struct Foo ...
impl io::Read for Foo ...

fn problem<'a>() -> io::Result<&'a mut io::Read> {
    // foo does not live long enough, because it gets allocated on the stack
    let mut foo = Foo{ v: 42 };
    Ok(&mut foo)
}

Rust playground is here.

Obviously, the problem is that foo is allocated on the stack, so if we return a reference to it, the reference outlives the object.

In C, you'd get around this by using malloc to allocate the object on the heap, and the caller would need to know to call free when appropriate. In a GCed language, this would just work since foo would stick around until there are no references to it. Rust is really clever, and kind of in-between, so I'm not sure what my options are.

I think one option would be to return a managed pointer type. Is Box the most appropriate? (I found a guide to pointers in rust, but it is way outdated.)

The reason I'm returning a reference is that in reality I need to return any of several structs which implement Read. I suppose another option would be to create an enum to wrap each of the possible structs. That would avoid heap allocation, but seems needlessly awkward.

Are there other options I haven't thought of?


Replacing the reference with a Box compiles successfully:

fn problem<'a>() -> io::Result<Box<io::Read>> {
    let mut foo = Foo{ v: 42 };
    Ok(Box::new(foo))
}