Borrowing & References
Borrowing lets code use data without taking ownership. Shared references (&T) allow concurrent readers. Mutable references (&mut T) grant exclusive write access.
Busca en todas las páginas de la documentación
Borrowing lets code use data without taking ownership. Shared references (&T) allow concurrent readers. Mutable references (&mut T) grant exclusive write access.
fn push_char(s: &mut String, c: char) {
s.push(c);
}
fn display(s: &str) {
println!("{s}");
}
fn main() {
let mut msg = String::from("hi");
display(&msg);
push_char(&mut msg, '!');
display(&msg);
}When to reach for this: Read-mostly APIs with &T, builders and mutation with &mut T, avoiding ownership transfer.
fn split_at_mut<T>(slice: &mut [T], mid: usize) -> (&mut [T], &mut [T]) {
slice.split_at_mut(mid)
}
fn main() {
let mut data = vec![1, 2, 3, 4];
let (left, right) = split_at_mut(&mut data, 2);
left[0] = 10;
right[0] = 40;
println!("{:?}", data);
}What this demonstrates:
&mut for mutationsplit_at_mut creates two non-overlapping &mut slices safelyleft/right go out of scope&str/&[T] follow same rules&T or exactly one &mut Tlet mut s = String::from("a");
let r1 = &mut s;
let r2 = &*r1; // reborrow shared while mutable loan active in subset
println!("{r2}");& Coercion&String -> &str, &Vec<T> -> &[T] via Deref.
&mut to same variable - Compile error. Fix: Scope splits, split_at_mut, or interior mutability.&mut active - Forbidden. Fix: End mutable borrow before shared read.& to local data - Dangling reference. Fix: Return owned value or tie lifetime to input.&mut - Extends loan. Fix: Limit borrow scope with blocks.&mut collection while pushing - Iterator invalidation. Fix: Collect indices first or use drain.| Alternative | Use When | Don't Use When |
|---|---|---|
| Owned parameter | Caller transfers value | Only reading or short mutation |
RefCell/Mutex | Shared mutation needed | Exclusive &mut works |
| Index + raw access | Unsafe hot paths | Safe abstractions suffice |
| Channels | Cross-thread handoff | Same-thread borrowing works |
Yes, with disjoint field borrows: fn f(a: &mut S, b: &mut T) on different fields via split borrows.
A reference pointing to freed or moved data. Prevented by lifetimes and borrow checker.
Yes. &mut is exclusive read/write access.
Yes with lifetime parameters: struct Holder<'a> { r: &'a str }.
Borrow valid for entire program - string literals, leaked allocations, static data.
At end of scope or last use (non-lexical lifetimes).
Yes. Closures capture by reference (&T, &mut T) or move.
No. References are safe, proven valid. Raw pointers need unsafe to dereference.
Bindings in match can be refs: match &mut v { ... }.
Held &mut across .await is often rejected. Use owned state or Mutex in async.
'a existsStack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Revisado por Chris St. John·Última actualización: 16 jul 2026