Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving to and from a mutably borrowed structure

Tags:

rust

Can someone explain why moving values into borrowed structs is valid while moving them out is not? For example:

struct S {
    v: Vec<u8>
}

fn move_v_out(s: &mut S) {
    let old_vecotr = s.v; // If removed, program compiles fine
    s.v = vec![];
}

fn main() {
    let mut v = S {
        v: vec![]
    };
    move_v_out(&mut v);
}

In either case, a member of a mutably-borrowed structure is modified. However one causes a compilation error.

like image 645
urubi Avatar asked Feb 14 '15 08:02

urubi


People also ask

What is mutable borrowing in rust?

Using sample codes, Mutable Borrowing in Rust means the owner passes the variable’s ownership to a function but making the variable open to value change. The function definition must specify the parameter with &mut before the type. For instance, line 1 has this parameter definition – v: &mut i32.

Can We mutably borrow a player that is stilled immutably borrowed?

We've then tried to mutably borrow our_player while it is stilled immutably borrowed. Wait, what??? Yes, so when we create a borrow like this: let my_immutable_return = immutable_borrow (&our_player); It does not get "returned to its owner" until the curly brace after it.

What is a move and a borrow?

Unlike a move, a borrow, as we already introduced in a code example above, is when you pass a reference to data rather than the data itself using the &. However, there are two types of borrows and we've only shown one thus far: This is what we demonstrated above. Just to review: immutable_borrow (&our_player); println!

What is the difference between move and borrow in rust?

Rust automatically destroys data for you, so you won't be seeing any delete s. Unlike a move, a borrow, as we already introduced in a code example above, is when you pass a reference to data rather than the data itself using the &. However, there are two types of borrows and we've only shown one thus far:


1 Answers

The main difference is that when you move a value from a borrowed struct, you leave it into a "partially moved state", which forbids it to be used as a whole struct afterwards.

And this state is forbidden for borrowed values, as they need to be still valid at the end of the function and the compiler doesn't (yet ?) understand that you are setting the value properly afterwards.

However, if what you want to do is extract the old Vec and replace it by a new one, the standard library contains exactly the function you need: std::mem::replace

fn move_v_out(s: &mut S) {
    let old_vector = std::mem::replace(&mut s.v, vec![]);
    // do something with old_vector
}
like image 141
Levans Avatar answered Sep 24 '22 06:09

Levans