Hello, I am new to rust.I have so many questions about borrowing
during the process of learning Rust. Is there any unified and detailed explanation of borrowing in Rust? Oh, Let me first raise two specific questions:
Env: rustc 1.82.0 (f6e511eec 2024-10-15)
Question 1: Dereferencing vs. Direct Borrowing in Rust
I’m confused about the difference between *&T
and T
in borrowing. The following code compiles with let b = &mut *a
, but fails with let b = &mut x
. Why does *a
behave differently from x
in this context?
Additionally, uncommenting the last line (*b = ...
) causes the error:
cannot assign to
*a
because it is borrowed
fn annoying_borrow() {
let mut x = Box::new(1);
let a = &mut x;
let b = &mut *a;
// let b = &mut x; // error: cannot borrow `x` as mutable more than once at a time
*a = Box::new(2);
// *b = Box::new(3); // error: `*a` is assigned to here but it was already borrowed
}
Does using the *a
instead of the x
here further imply the subtle difference between them? Emmm, what I really want to explore is not the difference between *a
and x
, but the rules of borrowing in the Rust type system (compiler).
Question 2: Reborrowing from References
The reborrow_from_imutable
fail to compile, while normal_borrow
works. The only difference is the presence of an immutable reference r
to w
. Does reborrowing from an immutable reference (let r0 = &r.0
) extend the lifetime of r
, preventing mutable access to w.1
?
fn normal_borrow() {
let mut w = (0, 1);
let r0 = &w.0;
let m1 = &mut w.1;
println!("{}", r0);
}
fn reborrow_from_imutable() {
let mut w = (0, 1);
let r = &w;
let r0 = &r.0;
let m1 = &mut w.1; // error: cannot borrow `w.1` as mutable because it is also borrowed as immutable
println!("{}", r0);
}
Background:
I’ve referenced Programming Rust, 2nd Ed. (Chapter 5), but I cannot fully comprehend this knowledge:
Shared access is read-only access.
Values borrowed by shared references are read-only. Across the lifetime of a
shared reference, neither its referent, nor anything reachable from that referent,
can be changed by anything. There exist no live mutable references to anything in
that structure, its owner is held read-only, and so on. It’s really frozen.
What's mean of the that structure
? Maybe the referent and the anything reachable from the referent
?
Mutable access is exclusive access.
A value borrowed by a mutable reference is reachable exclusively via that reference. Across the lifetime of a mutable reference, there is no other usable path to
its referent or to any value reachable from there. The only references whose lifetimes may overlap with a mutable reference are those you borrow from the mutable reference itself.
Since mutable references are exclusive, why is it still allowed to borrow new mutable references from mutable references?
I wonder if there is any unified and detailed explanation of borrowing in Rust. Perhaps there used to be a clear set of rules about borrowing in Rust, but with the compiler continuously relaxing syntax restrictions (to facilitate coding in certain scenarios?), the current rules are more chaotic?