Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the options to end a mutable borrow in Rust?

I'm strugglin' with the borrow checker - wonder o' wonder.

While I found a solution by adding a block, I am curious if there are other ways to end a mutable borrow so the next statement can access a binding afterwards.

Here's what I did so far:

let mut canvas: Canvas = Canvas {
    width: 5,
    height: 5,
    array: vec!['x'; 5*5],
};

{
    let mut renderer: CanvasRenderer = CanvasRenderer::new(&mut canvas);

    renderer.render_point('x', 3, 3);
}

println!("The Value in the array is: {}", canvas.array[9]);

I wrap a block around the binding of a CanvasRenderer object and after mutating the canvas and the scope ends, the CanvasRenderer dies and my mutable borrowed canvas is available to be read or whatever.

This works - but now I'd like to see other solutions!

I heard about drop(stuff) but it did not work as I thought it should.

like image 311
xetra11 Avatar asked Mar 03 '16 07:03

xetra11


People also ask

How do you pass a mutable reference in Rust?

Mutable References First, we change s to be mut . Then we create a mutable reference with &mut s where we call the change function, and update the function signature to accept a mutable reference with some_string: &mut String . This makes it very clear that the change function will mutate the value it borrows.

What is a mutable reference in Rust?

Mutable data can be mutably borrowed using &mut T . This is called a mutable reference and gives read/write access to the borrower.

How does borrowing work in Rust?

An Example of Borrowing in RustYou can borrow the ownership of a variable by referencing the owner using the ampersand (&) symbol. Without borrowing by referencing, the program would panic. It would violate the ownership rule that a value can have one owner, and two variables cannot point to the same memory location.


1 Answers

There is no other way; using blocks is the way to do it. Before Rust 2018 (available in Rust 1.31) all borrows are lexical, that is, they always correspond to some lexical scope. The only scope which is larger than a single statement is that of a block, so blocks are your only tool to limit borrow scopes.

drop() would not work for two reasons: first, because it would require non-lexical scope which is not supported before Rust 2018, and second, it cannot be a general-purpose tool for managing borrows: for example, it wouldn't be able to end an immutable borrow simply because immutable references are Copy and can't be "dropped".

See also:

  • Moved variable still borrowing after calling `drop`?
  • What are non-lexical lifetimes?
like image 145
Vladimir Matveev Avatar answered Sep 21 '22 21:09

Vladimir Matveev