Borrow vs Move (when to use what)

Let's say we have box_int variable, assume it's a large data on a heap allocated memory.

let mut box_int = Box::new<u32>(22);
box_int = move_and_return(box_int);
use_as_ref(&mut box_int);


fn move_and_return(a: Box<u32>) -> Box<u32> { a }
fn use_as_ref(a: &mut Box<u32>) -> {}

As I know the first method doesn't copy/move data, so no memcopy or anything (is it always case?).

I'm confused why to use & and &mut, if we can just move, change if needed, and return (I assume no actual move of the data on heap occurs)

Because move_and_return will only work with Box<u32>, and not Rc<u32> or Arc<u32> or Cow<u32> or any other kind of container. Borrows separate access from storage: it doesn't matter where or how a value is stored, you can still pass a borrow around.

2 Likes

You can't always move. Imagine a tree. If you wanted to perform every operation on the tree by moving, then you'd always need to pass ownership of the entire tree even if an operation only needed the leaves. That's obviously not feasible.

If for example the tree has unbounded fanout, then you'd always have to rebuild every internal node from scratch each time.

Constant-time popping from a Vec would also be completely impossible. You'd have to turn the Vec into a by-value iterator and re-collect every element but the last one, every single time you needed to pop the last element. Utterly inefficient and roundabout.

2 Likes

would it be more common to do this, anyway?

fn use_as_ref(a: &mut u32) { /* … */ }

And give the caller the power to call as_mut on a box or otherwise work with non-boxed values?

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.