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?
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.
Back to Rust. A mutable reference is a borrow to any type mut T , allowing mutation of T through that reference. The below code illustrates the example of a mutable variable and then mutating its value through a mutable reference ref_i .
Mutability is a property of either a borrow ( &mut ) or a binding ( let mut ). This means that, for example, you cannot have a struct with some fields mutable and some immutable: struct Point { x: i32, mut y: i32, // Nope. }
To accomplish this, Rust uses a borrowing mechanism. Instead of passing objects by value ( T ), objects can be passed by reference ( &T ). The compiler statically guarantees (via its borrow checker) that references always point to valid objects.
Use Rust 2018.
In Rust 2018, which has NLL, your example is valid.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With