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:
- Cada valor em Rust tem uma variável que é chamada de seu owner (dono).
- Só pode haver um dono por vez.
- 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.
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 🧠
- O que acontece com a memória quando uma variável sai de escopo no Rust?
- Explique por que o Rust "move" os dados da Heap em vez de copiá-los por padrão.
- Qual a diferença entre
CopyeClone?
Próxima Aula: Vamos aprender a compartilhar dados sem mover o dono com Borrowing e Referências! 🤝