🎯 Regras de Propriedade no Rust

Em poucas palavras

Ownership (Propriedade) é o sistema de gerenciamento de memória do Rust. Através de um conjunto de regras verificadas em tempo de compilação, o Rust garante a segurança da memória sem a necessidade de um Garbage Collector (coletor de lixo) ou de gerenciamento manual (como malloc/free em C).


📝 Notas e Desenvolvimento

1. As Três Regras de Ouro

Para garantir a segurança, o Rust impõe três regras estritas:

  1. Cada valor em Rust tem uma variável que é chamada de seu proprietário.
  2. Pode haver apenas um proprietário por vez.
  3. Quando o proprietário sai do escopo (scope), o valor é descartado (a função drop é chamada automaticamente).

2. Movimentação (Move) vs. Cópia (Copy)

O comportamento de uma atribuição depende de onde os dados estão armazenados na memória:

  • Tipos na Stack (Copy): Tipos simples com tamanho fixo (como i32, bool, f64) são copiados. A variável original permanece válida.
  • Tipos na Heap (Move): Tipos complexos (como String ou Vec) transferem a propriedade. A variável original torna-se inválida.

Erro de Compilação

Tentar usar uma variável que sofreu um “Move” resultará em um erro de compilação, prevenindo o erro de “double free” (liberação dupla de memória).

3. Propriedade em Funções

Passar um valor para uma função é semanticamente igual a uma atribuição:

fn main() {
    let s = String::from("texto"); // s é o proprietário
    toma_propriedade(s);           // O valor de s é MOVIDO para a função
    // println!("{s}");            // ERRO! s não é mais válido aqui.
 
    let x = 5;                     // x está na stack
    faz_copia(x);                  // x é COPIADO para a função
    println!("{x}");               // OK! x ainda é válido.
}
 
fn toma_propriedade(texto: String) {
    println!("{texto}");
} // Aqui 'texto' sai de escopo e drop() é chamado. Memória liberada.
 
fn faz_copia(numero: i32) {
    println!("{numero}");
} // Aqui 'numero' sai de escopo, mas nada especial acontece.

4. Retorno de Valores

Funções também podem transferir a propriedade de volta para quem as chamou através do return.

fn main() {
    let s1 = cria_string();         // Recebe a propriedade de cria_string
    let s2 = String::from("oi");
    let s3 = recebe_e_devolve(s2);  // s2 é movido para dentro e devolvido para s3
} 
 
fn cria_string() -> String {
    String::from("olá")             // Retorna e move a propriedade para fora
}
 
fn recebe_e_devolve(uma_string: String) -> String {
    uma_string                      // Devolve a propriedade
}

🔗 Conexões e Contexto


📚 Referências e Fontes

📂 Outros Conteúdos Preservados

🔗 Conceitos Relacionados