Pular para conteúdo

Aula 05 - Ownership (Parte 1) 🧠

Objetivo

Objetivo: Compreender o conceito de Ownership (Posse), a base da segurança de memória do Rust, e como ele gerencia dados sem a necessidade de um Garbage Collector.


1. Stack vs Heap 🏗️

Para entender o Ownership, precisamos saber onde os dados moram:

  • Stack (Pilha): Rápida, tamanho fixo conhecido em tempo de compilação. Armazena tipos primitivos (i32, bool, etc).
  • Heap (Monte): Mais lenta, tamanho dinâmico. Armazena dados complexos (String, Vec).

2. As Três Regras de Ouro do Ownership 📜

Rust gerencia a memória através de um conjunto de regras que o compilador verifica:

  1. Cada valor em Rust tem uma variável que é chamada de seu owner (dono).
  2. Só pode haver um dono por vez.
  3. Quando o dono sai de escopo, o valor é descartado (Drop).

3. String: O Exemplo Perfeito 🧵

Diferente de literais de string ("oi"), o tipo String é alocado na Heap.

{
    let s = String::from("olá"); // s é o dono da String
} // Aqui o escopo termina, e o Rust chama automaticamente a função 'drop' para limpar a memória.

4. Move vs Clone vs Copy 🔄

Move (Movimentação)

Quando atribuímos uma variável da Heap a outra, o Rust move o dono, invalidando a variável anterior. Isso evita o erro de "Double Free".

let s1 = String::from("texto");
let s2 = s1; // O dono agora é s2. s1 não é mais válido!
// println!("{}", s1); // ERRO de compilação!

Clone (Cópia Profunda)

Se quisermos copiar os dados da Heap, devemos usar explicitamente o método clone.

let s1 = String::from("texto");
let s2 = s1.clone(); // Cria uma nova cópia na Heap
println!("s1 = {}, s2 = {}", s1, s2); // OK!

Copy (Cópia da Stack)

Tipos com tamanho conhecido (como inteiros) são copiados automaticamente na Stack.

let x = 5;
let y = x; // Cópia rápida na Stack. x continua válido.

5. Visualização: O Conceito de Move 🚚

graph LR
    subgraph "Antes"
        s1_a[s1: dono] --> Data[("Dados na Heap: 'texto'")]
    end
    subgraph "Depois de let s2 = s1"
        s1_b[s1: Inválido]
        s2_b[s2: dono] --> Data
    end
    style s1_b fill:#f66,stroke:#333

6. Mini-Projeto: Gerenciador de Buffer 💾

Crie um programa que faça o seguinte: 1. Uma função que cria e retorna uma String (passando o Ownership para quem chama). 2. Uma função que recebe uma String por Ownership, adiciona um sufixo e a retorna de volta. 3. Demonstre o que acontece se você tentar usar uma variável após passá-la para uma função que não a retorna.


7. Exercício de Fixação 🧠

  1. O que acontece com a memória quando uma variável sai de escopo no Rust?
  2. Explique por que o Rust "move" os dados da Heap em vez de copiá-los por padrão.
  3. Qual a diferença entre Copy e Clone?

Próxima Aula: Vamos aprender a compartilhar dados sem mover o dono com Borrowing e Referências! 🤝