<h2>Entendendo o Sistema de Ownership e Borrowing</h2>
<p>O Rust resolve o problema de gerenciamento de memória através de um sistema único: o <strong>ownership</strong>. Cada valor tem um proprietário, e quando esse proprietário sai do escopo, a memória é liberada. Porém, nem sempre queremos transferir propriedade de um dado. É aí que entra o borrowing: permite usar um valor sem tomar posse dele. Existem dois tipos de referências: <code>&T</code> (imutável) e <code>&mut T</code> (mutável). Entender a diferença é fundamental para escrever código Rust seguro.</p>
<p>O sistema é regido por três regras simples: você pode ter múltiplas referências imutáveis <strong>ou</strong> uma única referência mutável, mas nunca ambas simultaneamente. Isso previne data races em tempo de compilação, eliminando bugs sutis que causam problemas em outras linguagens.</p>
<pre><code class="language-rust">fn main() {
let s = String::from("Rust");
// Referência imutável - podemos ter várias
let r1 = &s;
let r2 = &s;
println!("{}, {}", r1, r2); // OK: ambas usam s
// s ainda é proprietário dos dados
println!("{}", s);
}</code></pre>
<h2>Referências Imutáveis (&)</h2>
<p>Uma referência imutável <code>&T</code> permite ler um valor sem modificá-lo e sem tomar posse. É como emprestar um livro para alguém ler, mas você continua sendo o dono. Você pode criar quantas referências imutáveis quiser do mesmo dado, pois ninguém está modificando nada. Quando você passa <code>&s</code> para uma função, apenas a referência é passada, não os dados.</p>
<p>O ponto crítico é que enquanto existem referências imutáveis ativas, você não pode modificar o valor original. O compilador garante isso. Funções que recebem <code>&T</code> não podem mudar o conteúdo, e o Rust força isso em tempo de compilação.</p>
<pre><code class="language-rust">fn calcular_comprimento(s: &String) -> usize {
s.len()
} // s sai do escopo, mas como não é proprietário, nada acontece
fn main() {
let s1 = String::from("hello");
let len = calcular_comprimento(&s1);
println!("'{}' tem comprimento {}", s1, len); // s1 ainda é válido
}</code></pre>
<p>Um exemplo prático: ao iterar sobre uma coleção em uma função, você frequentemente quer apenas ler os dados. Passar uma referência imutável evita cópia desnecessária:</p>
<pre><code class="language-rust">fn processar_nomes(nomes: &Vec<String>) {
for nome in nomes {
println!("Nome: {}", nome);
}
}
fn main() {
let lista = vec![
String::from("Alice"),
String::from("Bob"),
];
processar_nomes(&lista);
processar_nomes(&lista); // Podemos chamar várias vezes
println!("{:?}", lista); // lista continua acessível
}</code></pre>
<h2>Referências Mutáveis (&mut)</h2>
<p>Uma referência mutável <code>&mut T</code> permite modificar o valor emprestado. É como emprestar o livro, mas quem o recebe tem permissão para escrever nele. A restrição crucial é <strong>uma única referência mutável por escopo</strong>: você não pode ter duas <code>&mut</code> apontando para o mesmo dado simultaneamente, nem pode ter uma <code>&</code> e uma <code>&mut</code> juntas. Isso previne condições de corrida e modificações inesperadas.</p>
<p>Quando você passa <code>&mut s</code>, está dizendo "você pode modificar isso, mas é a única pessoa que pode". O compilador força essa exclusividade. Se você tentar violar as regras, terá um erro clara: "cannot borrow <code>x</code> as mutable more than once".</p>
<pre><code class="language-rust">fn adicionar_exclamacao(s: &mut String) {
s.push_str("!");
}
fn main() {
let mut s = String::from("Hello");
adicionar_exclamacao(&mut s);
println!("{}", s); // Output: Hello!
}</code></pre>
<p>Aqui está um exemplo que falha e por quê:</p>
<pre><code class="language-rust">fn main() {
let mut x = 5;
let r1 = &mut x;
let r2 = &mut x; // ERRO: não pode ter duas referências mutáveis
println!("{}, {}", r1, r2);
}</code></pre>
<p>O compilador rejeita isso porque <code>r2</code> violaria a exclusividade. Porém, se você estruturar o código para que a primeira referência saia de escopo antes da segunda ser usada, funciona:</p>
<pre><code class="language-rust">fn main() {
let mut x = 5;
let r1 = &mut x;
println!("{}", r1); // r1 usado aqui
let r2 = &mut x; // OK: r1 não está mais em uso
println!("{}", r2);
}</code></pre>
<h3>Mixing Referências (o que NÃO fazer)</h3>
<pre><code class="language-rust">fn main() {
let mut s = String::from("Hello");
let r1 = &s; // Referência imutável
let r2 = &s; // Outra referência imutável
let r3 = &mut s; // ERRO: não pode ter &mut enquanto há &
println!("{}, {}, {}", r1, r2, r3);
}</code></pre>
<h2>Boas Práticas e Padrões Comuns</h2>
<p>Rust força boas práticas através de erros de compilação. Quando você está projetando uma API, prefira <code>&T</code> por padrão a menos que realmente precise modificar o valor. Use <code>&mut T</code> quando a função necessita alterar seus argumentos. Para tipos que implementam <code>Copy</code> (como inteiros), às vezes não vale a pena referenciar, pois a cópia é barata.</p>
<p>Um padrão comum é usar <code>&[T]</code> em vez de <code>&Vec<T></code> em parâmetros de função, pois slices são mais genéricas e funcionam com arrays também:</p>
<pre><code class="language-rust">fn somar_elementos(nums: &[i32]) -> i32 {
nums.iter().sum()
}
fn main() {
let vetor = vec![1, 2, 3, 4, 5];
let array = [10, 20, 30];
println!("Vetor: {}", somar_elementos(&vetor));
println!("Array: {}", somar_elementos(&array));
}</code></pre>
<p>Para modificações, use <code>&mut</code> conscientemente. Se sua função modifica um vetor, deixe isso explícito na assinatura:</p>
<pre><code class="language-rust">fn limpar_espacos(s: &mut String) {
s.retain(|c| !c.is_whitespace());
}
fn main() {
let mut texto = String::from("Hello World");
limpar_espacos(&mut texto);
println!("{}", texto); // Output: HelloWorld
}</code></pre>
<h2>Conclusão</h2>
<p>O sistema de borrowing em Rust é seu maior trunfo para evitar bugs de memória. Lembre-se: <strong>uma única referência mutável ou múltiplas imutáveis, nunca ambas</strong>. Use <code>&T</code> para leitura e <code>&mut T</code> apenas quando necessário modificar. Essa aparente restrição é na verdade liberdade — liberdade de não se preocupar com data races, use-after-free ou double-frees. Dominando referências, você domina Rust.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html" target="_blank" rel="noopener noreferrer">The Rust Book - Ownership</a></li>
<li><a href="https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html" target="_blank" rel="noopener noreferrer">The Rust Book - References and Borrowing</a></li>
<li><a href="https://doc.rust-lang.org/rust-by-example/scope/borrow.html" target="_blank" rel="noopener noreferrer">Rust by Example - Borrowing</a></li>
<li><a href="https://doc.rust-lang.org/std/" target="_blank" rel="noopener noreferrer">Official Rust Standard Library Documentation</a></li>
<li><a href="https://www.oreilly.com/library/view/programming-rust/9781491927281/" target="_blank" rel="noopener noreferrer">Programming Rust: Fast, Safe Systems Development - Jim Blandy & Jason Orendorff</a></li>
</ul>