Baseado no roadmap do arquivo rust.pdf.
Aprender Rust de forma progressiva: primeiro a linguagem, depois organização de projetos, testes, concorrência, bibliotecas do ecossistema e projetos práticos.
- Estude em ciclos curtos: leia, escreva código, rode, quebre e corrija.
- Para cada tópico, crie pequenos arquivos ou projetos com
cargo new. - Não avance rápido demais em ownership, borrowing e lifetimes. Esses conceitos sustentam quase todo o resto.
- Ao final de cada etapa, faça o projeto sugerido antes de seguir.
- O que é Rust.
- Por que usar Rust.
- Instalação do Rust e Cargo.
- Uso do Rust Playground.
- Configuração de IDE/editor.
Rust é uma linguagem de sistemas focada em segurança de memória, performance e concorrência. Ela evita muitos erros comuns sem depender de garbage collector.
Cargo é a ferramenta principal para criar projetos, compilar, rodar testes, baixar dependências e publicar pacotes.
rustc --version
cargo --version
cargo new hello_rust
cd hello_rust
cargo run
cargo build
cargo checkQuando criar um projeto Rust, adicione um arquivo .gitignore para não versionar arquivos gerados pela compilação.
Exemplo básico:
/target
Cargo.lockObservação: em aplicações finais, normalmente você versiona o Cargo.lock. Em bibliotecas, é comum deixar o Cargo.lock fora do Git.
Crie um projeto hello_rust que imprime seu nome, idade e uma frase usando variáveis.
- Variáveis.
- Mutabilidade.
- Constantes.
- Tipos de dados.
- Controle de fluxo.
- Funções.
- Métodos.
- Pattern matching.
- Desestruturação.
Em Rust, variáveis são imutáveis por padrão.
let nome = "Joao";
let mut idade = 30;
idade += 1;
const LIMITE: u32 = 100;- Inteiros:
i32,u32,usize. - Ponto flutuante:
f32,f64. - Booleanos:
bool. - Caracteres:
char. - Strings:
Stringe&str. - Tuplas.
- Arrays.
Estude:
if,else if,else.loop.while.for.match.
fn soma(a: i32, b: i32) -> i32 {
a + b
}let numero = 2;
match numero {
1 => println!("um"),
2 => println!("dois"),
_ => println!("outro"),
}Crie uma calculadora simples com funções para somar, subtrair, multiplicar e dividir.
struct.enum.trait.- Blocos
impl.
Use structs para representar dados relacionados.
struct Usuario {
nome: String,
ativo: bool,
}
impl Usuario {
fn novo(nome: String) -> Self {
Self { nome, ativo: true }
}
}Enums representam valores que podem assumir uma entre várias formas.
enum Status {
Pendente,
Concluido,
Cancelado,
}Traits definem comportamento compartilhado.
trait Descrever {
fn descrever(&self) -> String;
}Modele um sistema de tarefas:
- Uma
struct Tarefa. - Um
enum Status. - Um método para marcar tarefa como concluída.
- Um trait
Resumoque retorna uma descrição da tarefa.
Array.Vec.HashMap.HashSet.LinkedList.- Pilha.
- Fila.
BinaryHeap.BTreeMap.BTreeSet.
Priorize:
Vec<T>.HashMap<K, V>.HashSet<T>.
Essas estruturas aparecem com muita frequência em programas reais.
use std::collections::HashMap;
fn main() {
let mut notas = HashMap::new();
notas.insert("Ana", 9);
notas.insert("Joao", 8);
for (aluno, nota) in notas {
println!("{aluno}: {nota}");
}
}Crie um contador de palavras:
- Receba uma frase.
- Separe as palavras.
- Conte quantas vezes cada palavra aparece usando
HashMap.
- Regras de ownership.
- Segurança de memória.
- Borrowing.
- Referências.
- Slices.
- Diferença entre stack e heap.
- Cada valor em Rust tem um dono.
- Só pode existir um dono por vez.
- Quando o dono sai de escopo, o valor é descartado.
Use referências quando quiser emprestar um valor sem transferir ownership.
fn tamanho(texto: &String) -> usize {
texto.len()
}
fn main() {
let nome = String::from("Rust");
println!("{}", tamanho(&nome));
println!("{}", nome);
}fn adicionar(texto: &mut String) {
texto.push_str(" language");
}let texto = String::from("aprendendo rust");
let parte = &texto[0..10];Faça funções que:
- Recebem
Stringpor valor. - Recebem
&String. - Recebem
&str. - Recebem
&mut String.
Compare o que compila e o que não compila.
Option<T>.Result<T, E>.- Operador
?. - Tipos de erro customizados.
- Traits de erro.
Use Option quando um valor pode existir ou não.
fn primeiro(v: Vec<i32>) -> Option<i32> {
v.first().copied()
}Use Result quando uma operação pode falhar.
use std::fs;
fn ler_arquivo(caminho: &str) -> Result<String, std::io::Error> {
fs::read_to_string(caminho)
}fn ler_config() -> Result<String, std::io::Error> {
let conteudo = std::fs::read_to_string("config.txt")?;
Ok(conteudo)
}Crie um programa que lê um arquivo, conta suas linhas e trata erro caso o arquivo não exista.
- Organização de código.
- Módulos.
- Crates.
- Namespacing.
- Dependências no
Cargo.toml. - Publicação no crates.io.
meu_projeto/
Cargo.toml
src/
main.rs
lib.rs
usuarios.rs
mod usuarios;
fn main() {
usuarios::criar();
}cargo add serde
cargo add serde_jsonSe cargo add não estiver disponível, edite o Cargo.toml manualmente.
Separe o projeto de tarefas em módulos:
tarefa.rs.status.rs.main.rs.
- Testes unitários.
- Testes de integração.
- Mocks.
- Testes baseados em propriedades.
fn soma(a: i32, b: i32) -> i32 {
a + b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn soma_dois_numeros() {
assert_eq!(soma(2, 3), 5);
}
}cargo testAdicione testes para a calculadora e para o sistema de tarefas.
- Definição e implementação de traits.
- Trait bounds.
- Associated types.
- Generics.
- Programação em nível de tipo.
fn primeiro<T>(lista: &[T]) -> Option<&T> {
lista.first()
}use std::fmt::Display;
fn imprimir<T: Display>(valor: T) {
println!("{valor}");
}Crie uma função genérica que recebe uma lista e retorna o maior item. Depois imponha os trait bounds necessários.
- Lifetimes.
- Anotações explícitas.
- Regras de elisão.
- Covariância e contravariância.
Lifetimes dizem ao compilador por quanto tempo referências são válidas. Muitas vezes Rust infere isso automaticamente, mas em funções que retornam referências pode ser necessário declarar.
fn maior<'a>(a: &'a str, b: &'a str) -> &'a str {
if a.len() > b.len() {
a
} else {
b
}
}Crie funções que retornam referências e observe quando o compilador exige anotações de lifetime.
- Threads.
- Channels.
- Message passing.
- Operações atômicas.
- Memory barriers.
- Futures.
asynceawait.
std::thread.std::sync::mpsc.Arc<T>.Mutex<T>.RwLock<T>.
use std::thread;
fn main() {
let handle = thread::spawn(|| {
println!("executando em outra thread");
});
handle.join().unwrap();
}Crie um programa que divide uma lista de números entre várias threads e soma os resultados parciais.
async.await.- Runtimes assíncronos.
- Tokio.
- async-std.
- smol.
Comece com Tokio, pois é muito usado no ecossistema Rust.
tokio.reqwest.hyper.quinn.
Crie um programa que faz requisições HTTP para várias URLs em paralelo e imprime o status de cada resposta.
- Macros declarativas com
macro_rules!. - Macros procedurais.
- Custom derive.
- DSLs.
macro_rules! ola {
() => {
println!("Ola, Rust!");
};
}
fn main() {
ola!();
}Crie uma macro simples para imprimir mensagens de log com prefixo.
Bibliotecas citadas no roadmap:
- Axum.
- Actix.
- Rocket.
- Leptos.
- Loco.
Recomendação do roadmap: Axum.
serde.json-rust.toml-rust.
Priorize serde com serde_json.
- Diesel.
- sqlx.
- rusqlite.
Comece por sqlx se quiser trabalhar com async e APIs web. Use rusqlite para projetos locais com SQLite.
clap.structopt.termion.
Priorize clap, pois structopt foi absorvido pelo ecossistema do clap.
ring.rust-crypto.sodiumoxide.
- Tauri.
- gtk-rs.
- relm.
- Bevy.
- Fyrox.
- ggez.
- macroquad.
- wgpu-rs.
- embedded-hal.
- rppal.
- nrf-hal.
- wasm-pack.
- wasm-bindgen.
- wasmer.
- Criterion.rs.
rustdoc.rust-gdb.rust-lldb.
Conceitos:
- Funções.
- Match.
- Entrada e saída.
- Tratamento básico de erro.
Conceitos:
- Strings.
- Slices.
HashMap.- Iteradores.
Conceitos:
- Structs.
- Enums.
- Traits.
- Módulos.
- Testes.
Conceitos:
Result.- Operador
?. - Erros de IO.
- Organização de código.
Conceitos:
- Dependências.
- Cargo.
- Argumentos de linha de comando.
- Separação entre binário e biblioteca.
Conceitos:
- Async.
- Tokio.
- Rotas.
- JSON com Serde.
- Estado compartilhado.
- Testes de handlers.
Conceitos:
- sqlx.
- SQLite ou Postgres.
- Migrações.
- Repositórios.
- Erros customizados.
Conceitos:
- Criterion.rs.
- Otimização.
- Comparação entre estruturas de dados.
- Instalação, Cargo e primeiro programa.
- Variáveis, tipos, controle de fluxo e funções.
- Structs, enums, impl e traits.
- Ownership, borrowing, referências e slices.
Option,Resulte operador?.- Coleções:
Vec,HashMap,HashSet. - Módulos, crates e dependências.
- Testes.
- Generics, trait bounds e associated types.
- Lifetimes.
- Concorrência com threads, channels,
ArceMutex. - Async com Tokio.
- Web com Axum.
- Banco de dados com sqlx.
- Macros.
- Performance, profiling e documentação.
- Instalar Rust.
- Aprender Cargo.
- Estudar variáveis, tipos, funções e controle de fluxo.
- Fazer a calculadora CLI.
- Estudar structs, enums, impl e traits.
- Estudar
Vec,HashMapeHashSet. - Fazer o contador de palavras.
- Estudar ownership, borrowing e slices.
- Refazer exercícios antigos corrigindo problemas de ownership.
- Fazer o gerenciador de tarefas.
- Estudar
Option,Result,?e erros customizados. - Estudar módulos e organização com Cargo.
- Adicionar testes aos projetos.
- Estudar generics, trait bounds e lifetimes.
- Melhorar os projetos anteriores usando código genérico onde fizer sentido.
- Estudar threads, channels,
Arc,MutexeRwLock. - Fazer projeto de soma paralela ou processamento paralelo de arquivos.
- Estudar async, await e Tokio.
- Fazer cliente HTTP assíncrono com
reqwest.
- Estudar Axum, Serde e sqlx.
- Fazer uma API REST simples com banco de dados.
- Instalei Rust e Cargo.
- Criei e rodei um projeto com
cargo run. - Entendi variáveis imutáveis e
mut. - Usei tipos básicos.
- Escrevi funções com retorno.
- Usei
if,loop,while,forematch. - Criei structs.
- Criei enums.
- Implementei métodos com
impl. - Criei e implementei traits.
- Usei
Vec. - Usei
HashMap. - Entendi as regras de ownership.
- Usei referências imutáveis.
- Usei referências mutáveis.
- Usei slices.
- Usei
Option. - Usei
Result. - Usei o operador
?. - Organizei código em módulos.
- Adicionei dependências no
Cargo.toml. - Escrevi testes unitários.
- Escrevi testes de integração.
- Usei generics.
- Usei trait bounds.
- Entendi lifetimes básicos.
- Criei threads.
- Usei channels.
- Usei
ArceMutex. - Escrevi código async com Tokio.
- Criei uma API com Axum.
- Serializei JSON com Serde.
- Usei banco de dados com sqlx ou rusqlite.
- Fiz benchmark com Criterion.rs.
- Gerei documentação com
cargo doc.
cargo new nome_do_projeto
cargo run
cargo build
cargo build --release
cargo check
cargo test
cargo doc --open
cargo fmt
cargo clippyComece pelo projeto hello_rust, depois faça a calculadora CLI. Enquanto escreve código, mantenha uma lista dos erros do compilador que você encontrou e o que aprendeu com cada um. Em Rust, entender as mensagens do compilador é parte central do aprendizado.