How to satisfy Rust loan checker with this simple code?

I get a Rust compilation error from the borrower verification tool and don’t know how to fix it.
The code below is simple and not a problem with similar code in C ++.

fn main() { let mut nums = vec![1, 2, 3]; if let Some(x) = nums.last() { nums.push(*x); } } 

Here is the error:

 message: 'cannot borrow `nums` as mutable because it is also borrowed as immutable (4, 9)' 
+5
source share
2 answers

You can dereference the link in the guard clause:

 fn main() { let mut nums = vec![1, 2, 3]; if let Some(&x) = nums.last() { nums.push(x); } } 

Rust has a powerful pattern matching feature, you can unzip almost everything if you know your type. Check Rust Pattern Matching Document .

+4
source

When you call .last() , you take nums as immutable, since mutation will invalidate the x link you are holding. Then you call .push , which borrows nums as mutable.

The problem is that you now have an unchangeable and mutable borrowing of the same value, which contradicts the rust memory safety guarantees (several readers or one copyright guarantee ensures that you never have invalid memory anywhere).

 fn main() { let mut nums = vec![1, 2, 3]; if let Some(x) = nums.last() { // Immutable borrow starts here nums.push(*x); // Mutable borrow starts here } // Immutable and mutable borrows end here } 

The solution would be to reduce the volume of immutable borrowing by immediately dropping the link to its result, according to the example of @DanielSanchez:

 let mut nums = vec![1, 2, 3]; if let Some(&x) = nums.last() { // Immutable borrow starts and ends here nums.push(x); // Mutable borrow starts here } // Mutable borrow ends here 
+7
source

Source: https://habr.com/ru/post/1270257/


All Articles