Reputation: 935
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
Reputation: 255
Use Rust 2018.
In Rust 2018, which has non-lexical lifetimes (NLL), your example is valid.
Upvotes: 10
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