user10714010
user10714010

Reputation: 935

Is it possible to unborrow a mutable reference in rust?

Here is an example

#[derive(Debug)]
struct Point {
    x: Vec<i32>,
    y: i32,
}

let mut p = Point { x: vec![1], y: 7 };

// borrow out mutable reference p to a and b
let Point { x: a, y: b } = &mut p;

// mutate a
a.push(2); 
// how do I get p back?
println!("{:?}", p);

Is there a way to unborrow the reference without creating a new block or abstract into function?

Upvotes: 8

Views: 4679

Answers (2)

Yusuke NOJIMA
Yusuke NOJIMA

Reputation: 255

Use Rust 2018.

In Rust 2018, which has non-lexical lifetimes (NLL), your example is valid.

Upvotes: 10

vikram2784
vikram2784

Reputation: 822

You can't. The fields x and y are (mutably) borrowed, which means Point is (mutably) borrowed. All this happens in the same scope, as a result Point will remain mutably borrowed until the end of the scope and you can't have a (immutable or mutable) borrow to the data after it is mutably borrowed. Interior Mutability is what you need to have a look at.

Using RefCell<T> :

use std::cell::RefCell;

#[derive(Debug)]
struct Point {
    x: RefCell<Vec<i32>>,
    y: i32,
}

fn main() {
    let p = Point {
        x: RefCell::new(vec![1]),
        y: 7,
    };

    (*p.x.borrow_mut()).push(2);

    println!("{:?}", p);
}

Edit 1: Yes, It is possible as per Yusuke NOJIMA's answer. You will need to add the attribute #![feature(nll)] to your code , using rust nightly.

#![feature(nll)]

#[derive(Debug)]
struct Point {
    x: Vec<i32>,
    y: i32,
}

...
...

For more, please refer the NLL RFC

Upvotes: 6

Related Questions