Da trilha de Rust Este conceito ainda não saiu como card do dia. ir para o card de hoje

Rust Memória Básico

Borrowing e referências

Em Rust, borrowing é o mecanismo que permite acessar um valor sem tomar posse dele. Em vez de mover o valor, você cria uma referência (&T ou &mut T) que aponta para ele. O compilador garante que as referências sejam sempre válidas e que não haja conflitos de acesso, evitando data races e use-after-free em tempo de compilação.

As regras do borrow checker são: você pode ter várias referências imutáveis (&T) ao mesmo tempo, ou uma única referência mutável (&mut T), mas nunca ambas simultaneamente. Além disso, uma referência não pode viver mais que o valor referenciado — isso evita referências pendentes (dangling references).

O escopo das referências é limitado ao bloco onde são criadas. O compilador analisa o tempo de vida (lifetime) das referências e garante que elas não ultrapassem o tempo de vida do dono. Assim, você pode emprestar um valor para uma função, modificá-lo ou lê-lo, e depois devolvê-lo intacto ao dono original.

Pontos-chave

  • &T cria uma referência imutável; &mut T cria uma referência mutável.
  • Você pode ter vários &T ao mesmo tempo, mas apenas um &mut T por vez.
  • Referências não podem viver mais que o valor que elas apontam (sem dangling references).
  • O escopo de uma referência termina quando ela deixa de ser usada, liberando o empréstimo.
  • O borrow checker impede data races e use-after-free em tempo de compilação.
borrowing.rs
// Exemplo de borrowing em Rust

fn calcular_comprimento(s: &String) -> usize {
    s.len() // apenas lê, não toma posse
}

fn adicionar_exclamacao(s: &mut String) {
    s.push('!'); // modifica através de referência mutável
}

fn main() {
    let mut texto = String::from("Olá");

    // Empréstimo imutável: podemos ter vários ao mesmo tempo
    let tam1 = calcular_comprimento(&texto);
    let tam2 = calcular_comprimento(&texto);
    println!("Comprimento: {} e {}", tam1, tam2);

    // Empréstimo mutável: só um por vez
    adicionar_exclamacao(&mut texto);
    println!("Depois: {}", texto);

    // O escopo do empréstimo termina aqui; texto continua válido
    let outro = &texto; // novo empréstimo imutável
    println!("Outro: {}", outro);
}

Exercícios

  1. 1
    Fácil

    Empréstimo imutável

    Escreva uma função primeira_palavra que recebe uma referência imutável a uma String e retorna a primeira palavra (até o primeiro espaço) como uma String nova. No main, crie uma String, chame a função e imprima o resultado. O dono original deve continuar válido após a chamada.

    Resolver
  2. 2
    Médio

    Empréstimo mutável e escopo

    Crie uma função dobrar_valores que recebe uma referência mutável a um Vec<i32> e multiplica todos os elementos por 2. No main, crie um vetor, chame a função e imprima o vetor modificado. Garanta que não haja empréstimos simultâneos conflitantes.

    Resolver
  3. 3
    Desafio

    Referências pendentes e escopo

    Escreva um programa que demonstre (e depois corrija) uma tentativa de criar uma referência pendente. Crie uma função criar_referencia_invalida que tenta retornar uma referência para uma variável local. O código não deve compilar; comente-o e mostre a versão corrigida que retorna uma String própria. Explique no código com comentários o que o compilador acusaria.

    Resolver

Continue estudando