Hello World em Rust: instalando e rodando no Ubuntu

Mascote do LinuxPro compilando o primeiro programa em Rust, Ferris na mesa e engrenagem 3D do Rust na parede

Todo mundo começa por um Hello, world!. Este post usa esse programa de três linhas como desculpa para instalar o Rust no Ubuntu direito, entender o que o cargo faz e sair daqui com um projeto que compila — em uns dez minutos.

Por que Rust, em duas frases

O Rust entrega desempenho de C sem coletor de lixo e, ao mesmo tempo, elimina em tempo de compilação a classe de bug que mais gera CVE em software de sistema: uso de memória depois de liberada, estouro de buffer, corrida entre threads. O preço é um compilador que discute com você na primeira semana.

Não é linguagem de nicho: o kernel Linux tirou o selo de experimental do Rust na versão 7.0, em abril de 2026, e o Ubuntu 26.04 LTS já entrega o sudo e os utilitários básicos reescritos nela. A história completa está em A história da linguagem Rust.

Instalando com rustup

Não use o apt install rustc. O Rust lança a cada seis semanas e o pacote da distro fica velho rápido — além de não dar o rustup, que é quem gerencia versões. O caminho oficial:

sudo apt update
sudo apt install -y build-essential curl    # o Rust usa o linker do GCC

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Aceite a instalação padrão (opção 1). Ao terminar, carregue o ambiente na sessão atual — nas próximas ele já entra sozinho pelo ~/.bashrc:

source "$HOME/.cargo/env"

rustc --version
cargo --version

Você deve ver algo como rustc 1.98.1. Se o comando não for encontrado, é porque o ~/.cargo/bin não entrou no PATH — o source acima resolve.

O primeiro programa, na unha

Antes do cargo, vale ver o compilador nu. Crie ola.rs:

fn main() {
    println!("Olá, mundo!");
}
rustc ola.rs
./ola

Duas coisas para reparar. O rustc gerou um binário nativo — sem VM, sem interpretador, sem runtime para instalar na máquina de destino. E o println! tem uma exclamação: em Rust, isso significa que é uma macro, não uma função comum. Você vai ver esse ponto de exclamação com frequência.

Agora do jeito certo: cargo

Na prática ninguém chama o rustc na mão. O cargo é o gerenciador de projeto, de dependências e de build — o equivalente ao que npm, pip e make fazem juntos em outras linguagens.

cargo new ola
cd ola
cargo run

Ele cria a estrutura, compila e executa. O que apareceu:

ola/
├── Cargo.toml      # nome, versão, dependências
├── .gitignore      # já vem pronto
└── src/
    └── main.rs     # o seu código

Os comandos que você vai usar todo dia:

cargo run                 # compila e executa
cargo build               # só compila (binário em target/debug/)
cargo build --release     # compila otimizado — bem mais lento, bem mais rápido
cargo check               # verifica se compila, SEM gerar binário (o mais rápido)
cargo test                # roda os testes
cargo fmt                 # formata o código no padrão da comunidade
cargo clippy              # o linter: pega o que compila mas é má ideia

O cargo check é o segredo de produtividade em Rust: enquanto você escreve, ele responde em uma fração do tempo do build, porque não gera código de máquina.

Se o clippy e o fmt não estiverem instalados:

rustup component add clippy rustfmt

Um passo além do “olá”: lendo a entrada

Um Hello, world! não mostra nada do que torna a linguagem diferente. Este mostra — troque o conteúdo de src/main.rs:

use std::io::{self, Write};

fn main() {
    print!("Qual o seu nome? ");
    io::stdout().flush().unwrap();

    let mut nome = String::new();
    io::stdin()
        .read_line(&mut nome)
        .expect("falha ao ler a entrada");

    let nome = nome.trim();

    if nome.is_empty() {
        println!("Você não digitou nada.");
    } else {
        println!("Olá, {nome}! Bem-vindo ao Rust.");
    }
}
cargo run

Três detalhes que valem mais que o programa:

  • let mut — em Rust tudo é imutável por padrão. Se você quer poder alterar, precisa dizer. É o inverso da maioria das linguagens, e é de propósito.
  • &mut nome — você está emprestando a variável para a função poder escrever nela, sem transferir a posse. Esse conceito é o coração do Rust; o compilador garante que só existe um empréstimo de escrita por vez.
  • .expect(...) — ler da entrada pode falhar, e o Rust obriga você a tratar isso. Não existe exceção escondida: ou você lida com o erro, ou o programa não compila.

Usando uma dependência

O crates.io é o repositório de pacotes da linguagem. Adicionar um é um comando:

cargo add rand

Isso escreve a dependência no Cargo.toml sozinho. Agora um sorteio:

use rand::Rng;

fn main() {
    let sorteado = rand::rng().random_range(1..=100);
    println!("Número sorteado: {sorteado}");
}
cargo run

Na primeira execução ele baixa e compila a dependência e todas as dela; nas seguintes usa o cache. O arquivo Cargo.lock, criado automaticamente, trava as versões exatas — versione ele junto com o projeto se for um binário.

Gerando o binário de produção

cargo build --release
ls -lh target/release/ola
./target/release/ola

O binário em release é otimizado e não depende do Rust estar instalado na máquina de destino — só das bibliotecas do sistema. É por isso que tanta ferramenta de linha de comando moderna é distribuída como um arquivo único.

Gerenciando versões do Rust

rustup update                    # atualiza a toolchain
rustup toolchain install nightly # instala o canal de desenvolvimento
cargo +nightly build             # compila com ele, sem trocar o padrão
rustup default stable            # volta ao estável
rustup show                      # o que está instalado e ativo

Para fixar a versão de um projeto específico, crie um rust-toolchain.toml na raiz — o rustup passa a respeitá-lo automaticamente ali dentro.

Quando travar

Vai travar, e não tem problema. O compilador do Rust é o mais didático que existe: ele costuma dizer não só o que está errado, mas o que escrever no lugar. Leia a mensagem inteira antes de procurar no Google — a resposta quase sempre está nela.

rustc --explain E0502     # explicação longa de qualquer código de erro

E, se ainda assim não sair, colar a mensagem num assistente de IA no terminal resolve a maior parte dos travamentos de iniciante sem tirar você do teclado.

Por onde seguir

Dez minutos, um binário nativo e um caranguejo. É um bom começo.

Engrenagem baseada no logo oficial do Rust (CC BY 4.0). Ferris, mascote extraoficial, por Karen Rustad Tölva.