Hacker News new | ask | show | jobs
by kam 4155 days ago
Yeah, it's unclear what he's talking about there. Normally when a function allocates a new object, it would want to return it by move (transferring ownership), rather than by reference. That doesn't involve any lifetimes.

    fn make_a_foo() -> Box<Foo> {
        Box::new(Foo { a: 5 })
    }
If the function allocated memory and only returned a borrowed reference, who would be responsible for freeing it? Yes, Rust will make you stop and think there, as it enforces memory safety.

In cases where it does make sense to return a reference to a new object, like allocating from an arena, the lifetime ('a) of the returned reference will be the same as the lifetime of the arena.

    fn new_from_arena<'a>(arena: &'a TypedArena<Foo>) -> &'a mut Foo {
        arena.alloc(Foo { a: 5 })
    }
But Rust can infer the lifetime, so that can be shortened to:

    fn new_from_arena(arena: &TypedArena<Foo>) -> &mut Foo {
        arena.alloc(Foo { a: 5 })
    }
1 comments

Any reason you would ever want to return a Box instead of just a Foo, which the caller can then put in a Box if so desired?
I can think of a case: when you want to return a type whose size is not known at runtime (a "dynamically-sized type" a.k.a. DST), then you need to stuff it behind something else whose size is known so that the compiler can statically determine how much memory to allocate before calling your function. You could use a reference for this task, but only if, as per Rust's usual rules, you have a parameter to your function whose lifetime you can tie it to. If you don't have such a parameter, then a Box is your next best bet.

Somewhat related to this, there's also currently a language deficiency where you can be forced to use Box when returning a closure from a function. This will be addressed shortly after 1.0.