Do zero ao deploy: Guia completo de Rust para iniciantes (2026)

Publicado em 2026-01-31 • leitura estimada • ~10 min

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

  1. Pratique ownership e borrowing: faça exercícios até internalizar os conceitos (rustlings é ótimo para isso).
  2. Estude lifetimes: anotações de tempo de vida (&'a str) são essenciais para código avançado.
  3. Aprenda traits: equivalente a interfaces, permitem polimorfismo e código genérico.
  4. Explore async/await: programação assíncrona para I/O de alta performance.
  5. Contribua para projetos open source: Rust tem comunidade acolhedora e projetos de todos os níveis.
  6. 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. Evite unwrap() 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.