Do zero ao deploy: Guia completo de Rust para iniciantes (2026)
Rust é uma linguagem de programação de sistemas que combina performance de baixo nível (comparável a C/C++) com segurança de memória garantida em tempo de compilação. Criada pela Mozilla e hoje mantida pela Rust Foundation, ganhou popularidade em infraestrutura crítica, backend de alta performance, WebAssembly e ferramentas de desenvolvedor. Este guia leva você do zero absoluto até fazer deploy de uma aplicação real em Rust.
Por que aprender Rust em 2026
- Segurança de memória sem garbage collector: elimina bugs clássicos (use-after-free, double-free, data races) em tempo de compilação, sem custo de runtime.
- Performance: controle fino sobre memória e zero-cost abstractions permitem otimizações agressivas.
- Concorrência sem medo: o sistema de tipos garante ausência de data races, tornando código concorrente confiável.
- Ecossistema em crescimento: crates (bibliotecas) maduras para web (Actix, Axum, Rocket), async (Tokio), CLI (clap), e muito mais.
- Adoção em produção: Microsoft, Amazon, Google, Meta, Discord, Cloudflare e muitas outras usam Rust em sistemas críticos.
- WebAssembly: Rust é uma das melhores linguagens para compilar para WASM, permitindo código performático no browser.
Instalando Rust: rustup
A forma padrão de instalar Rust é via rustup, gerenciador de versões e toolchain.
# Linux/macOS
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Windows: baixe rustup-init.exe de https://rustup.rs
Após instalação, verifique:
rustc --version # compilador
cargo --version # gerenciador de pacotes e build
Primeiro programa: Hello, World!
Crie um novo projeto com Cargo:
cargo new hello_rust
cd hello_rust
Cargo gera estrutura básica:
hello_rust/
├── Cargo.toml # manifesto do projeto (dependências, metadados)
└── src/
└── main.rs # código fonte
Abra src/main.rs:
fn main() {
println!("Hello, Rust!");
}
Compile e execute:
cargo run
Cargo compila e roda automaticamente. Output: Hello, Rust!
Conceitos fundamentais: Ownership e Borrowing
O diferencial de Rust está no sistema de ownership, que garante segurança de memória sem garbage collector.
Ownership: cada valor tem um dono único
fn main() {
let s1 = String::from("hello");
let s2 = s1; // ownership transferido (move)
// println!("{}", s1); // ERRO: s1 não é mais válido
println!("{}", s2); // OK
}
Quando s2 = s1, a ownership da String é movida para s2. s1 fica inválido. Isso previne double-free (duas variáveis tentando liberar a mesma memória).
Borrowing: emprestar referências sem transferir ownership
fn main() {
let s1 = String::from("hello");
let len = calcular_tamanho(&s1); // empresta referência
println!("'{}' tem {} caracteres", s1, len); // s1 ainda é válido
}
fn calcular_tamanho(s: &String) -> usize {
s.len()
}
&s1 cria uma referência imutável. A função pode ler, mas não modificar. s1 mantém ownership.
Referências mutáveis
fn main() {
let mut s = String::from("hello");
adicionar_mundo(&mut s);
println!("{}", s); // "hello, world!"
}
fn adicionar_mundo(s: &mut String) {
s.push_str(", world!");
}
Regra importante: pode haver múltiplas referências imutáveis OU uma única referência mutável, nunca ambas ao mesmo tempo. Isso previne data races em tempo de compilação.
Tipos básicos e estruturas
Tipos escalares
let inteiro: i32 = 42; // inteiro de 32 bits
let flutuante: f64 = 3.14; // ponto flutuante de 64 bits
let booleano: bool = true;
let caractere: char = 'R';
Structs (estruturas)
struct Usuario {
nome: String,
email: String,
ativo: bool,
}
fn main() {
let user = Usuario {
nome: String::from("Ana"),
email: String::from("ana@example.com"),
ativo: true,
};
println!("Usuário: {}", user.nome);
}
Enums e pattern matching
enum Resultado {
Sucesso(String),
Erro(String),
}
fn processar() -> Resultado {
Resultado::Sucesso(String::from("Operação concluída"))
}
fn main() {
match processar() {
Resultado::Sucesso(msg) => println!("OK: {}", msg),
Resultado::Erro(err) => println!("Erro: {}", err),
}
}
Pattern matching em Rust é exaustivo: o compilador garante que todos os casos são tratados.
Tratamento de erros: Result e Option
Rust não tem exceptions. Erros são valores explícitos via Result<T, E>.
use std::fs::File;
use std::io::Read;
fn ler_arquivo(caminho: &str) -> Result<String, std::io::Error> {
let mut arquivo = File::open(caminho)?; // ? propaga erro
let mut conteudo = String::new();
arquivo.read_to_string(&mut conteudo)?;
Ok(conteudo)
}
fn main() {
match ler_arquivo("dados.txt") {
Ok(texto) => println!("Conteúdo: {}", texto),
Err(e) => println!("Erro ao ler arquivo: {}", e),
}
}
O operador ? retorna erro automaticamente se Result for Err, caso contrário extrai o valor de Ok.
Criando uma API REST simples com Axum
Vamos criar uma API HTTP básica usando Axum (framework async moderno).
Adicione dependências em Cargo.toml
[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
Código da API (src/main.rs)
use axum::{
routing::{get, post},
Router, Json,
};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Usuario {
nome: String,
email: String,
}
async fn health_check() -> &'static str {
"OK"
}
async fn criar_usuario(Json(usuario): Json<Usuario>) -> Json<Usuario> {
println!("Usuário criado: {} ({})", usuario.nome, usuario.email);
Json(usuario)
}
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/health", get(health_check))
.route("/usuarios", post(criar_usuario));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await
.unwrap();
println!("Servidor rodando em http://localhost:3000");
axum::serve(listener, app).await.unwrap();
}
Execute e teste
cargo run
Em outro terminal:
# Health check
curl http://localhost:3000/health
# Criar usuário
curl -X POST http://localhost:3000/usuarios \
-H "Content-Type: application/json" \
-d '{"nome":"João","email":"joao@example.com"}'
Deploy: compilando para produção
Build otimizado
cargo build --release
Binário fica em target/release/. Copie para servidor e execute:
./target/release/nome_do_projeto
Deploy com Docker
Crie um Dockerfile:
# Build stage
FROM rust:1.75 AS builder
WORKDIR /app
COPY . .
RUN cargo build --release
# Runtime stage
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y libssl3 ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/nome_do_projeto /usr/local/bin/app
EXPOSE 3000
CMD ["app"]
Build e run:
docker build -t minha-api-rust .
docker run -p 3000:3000 minha-api-rust
Deploy em cloud (Fly.io exemplo)
# Instale flyctl
curl -L https://fly.io/install.sh | sh
# Login e deploy
fly launch
fly deploy
Fly.io detecta Dockerfile automaticamente e faz deploy. Sua API estará online em segundos.
Recursos essenciais para dominar Rust
- The Rust Book: doc.rust-lang.org/book - documentação oficial, didática e completa.
- Rustlings: github.com/rust-lang/rustlings - exercícios práticos guiados.
- Rust by Example: doc.rust-lang.org/rust-by-example - aprenda com exemplos.
- crates.io: repositório oficial de bibliotecas Rust.
- Tokio: runtime async para aplicações concorrentes.
- Axum / Actix / Rocket: frameworks web.
- Serde: serialização/desserialização (JSON, YAML, etc.).
Próximos passos
- Pratique ownership e borrowing: faça exercícios até internalizar os conceitos (rustlings é ótimo para isso).
- Estude lifetimes: anotações de tempo de vida (
&'a str) são essenciais para código avançado. - Aprenda traits: equivalente a interfaces, permitem polimorfismo e código genérico.
- Explore async/await: programação assíncrona para I/O de alta performance.
- Contribua para projetos open source: Rust tem comunidade acolhedora e projetos de todos os níveis.
- Construa projetos reais: CLI tools, APIs, parsers, ferramentas de build.
Armadilhas comuns para iniciantes
- Lutar contra o borrow checker: no início, o compilador vai rejeitar código que parece válido. Não tente "enganar" o sistema; entenda o que ele está protegendo.
- Usar
clone()demais: iniciantes clonam valores para evitar erros de borrow. Funciona, mas é ineficiente. Prefira referências quando possível. - Ignorar Result e Option: use
?,unwrap_or,match. Eviteunwrap()em produção (causa panic se erro). - Não usar Cargo corretamente: aprenda
cargo fmt(formatação),cargo clippy(linter),cargo test(testes).
Conclusão
Rust tem curva de aprendizado íngreme, mas os benefícios compensam: código seguro, rápido e confiável. A linguagem força você a pensar sobre ownership e tempo de vida, mas em troca elimina classes inteiras de bugs. Com prática, os conceitos se tornam naturais e você ganha superpoderes para construir sistemas robustos. Siga este guia, pratique com projetos reais, consulte a documentação oficial e em poucas semanas você estará escrevendo código Rust produtivo e fazendo deploys com confiança.