Referencias y Borrowing
Una referencia te permite usar un valor sin tomar su ownership — se escribe con &. El dueño original conserva el valor, y la referencia solo toma prestado (borrow) el acceso a él temporalmente.
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize {
s.len()
}The length of 'hello' is 5.
calculate_length toma prestado s1 a través de una referencia en vez de tomar su ownership, así que s1 sigue siendo perfectamente usable de vuelta en main después de la llamada.
Referencias mutables
Una referencia mutable, &mut T, permite que una función modifique el valor que toma prestado. Rust permite esto, pero con una restricción crucial: puedes tener o bien una referencia mutable, o cualquier número de referencias inmutables, a un valor a la vez — nunca ambas.
fn main() {
let mut s = String::from("hello");
change(&mut s);
println!("{}", s);
}
fn change(s: &mut String) {
s.push_str(", world");
}hello, world
Cómo se ve un conflicto de borrow real
Esto es genuinamente lo que reporta rustc cuando intentas crear una referencia mutable mientras una inmutable todavía está en uso — capturado de una ejecución real, no escrito para parecer plausible:
fn main() {
let mut s = String::from("hello");
let r1 = &s;
let r2 = &mut s;
println!("{}, {}", r1, r2);
}error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
--> main.rs:5:14
|
4 | let r1 = &s;
| -- immutable borrow occurs here
5 | let r2 = &mut s;
| ^^^^^^ mutable borrow occurs here
6 |
7 | println!("{}, {}", r1, r2);
| -- immutable borrow later used here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0502`.Esta regla es lo que descarta por completo las data races, en tiempo de compilación — dos partes de un programa nunca pueden terminar leyendo y escribiendo los mismos datos a la vez, porque el compilador simplemente no dejará que compile el código que lo permitiría.
Siguiente: strings y slices — la diferencia entre un String con ownership y un &str prestado (borrowed).
Practice Exercise
Escribe una función word_count(s: &String) -> usize que devuelva el número de palabras en s usando s.split_whitespace().count(). Llámala con una referencia a un String que contenga "the quick brown fox" e imprime el resultado.