Bem-vindo à terceira aula do nosso curso de Rust! Até agora, você já configurou o ambiente e conhece os fundamentos da linguagem. Nesta aula, vamos dar um passo prático: criar seu primeiro programa Rust usando o Cargo, o sistema de build e gerenciamento de pacotes oficial do Rust. O Cargo simplifica tarefas como compilar código, baixar dependências e executar testes, sendo essencial para qualquer projeto Rust, desde scripts simples até grandes aplicações.

Vamos começar com o comando cargo new, que cria um novo projeto Rust com uma estrutura de diretórios padrão. Em seguida, exploraremos os arquivos gerados, como Cargo.toml e src/main.rs. Depois, veremos como compilar e executar o projeto com cargo build e cargo run. Por fim, entenderemos o básico do arquivo de configuração Cargo.toml.

cargo new

O comando cargo new é a maneira mais rápida de iniciar um novo projeto Rust. Ele cria uma pasta com o nome do projeto, contendo uma estrutura básica de diretórios e arquivos. O Cargo também inicializa um repositório Git (a menos que você use a flag --vcs none).

Para criar um projeto chamado hello_world, abra o terminal e execute:

cargo new hello_world

Isso criará a seguinte estrutura (simplificada):

hello_world/
├── Cargo.toml
├── .gitignore
└── src/
    └── main.rs

O arquivo main.rs já vem com um esboço do clássico "Hello, world!":

fn main() {
    println!("Hello, world!");
}

Você pode especificar o tipo de projeto com a flag --lib para criar uma biblioteca em vez de um binário, ou --bin (padrão) para um executável. Se não quiser que o Cargo inicialize um repositório Git, use --vcs none.

Estrutura do projeto

Um projeto Cargo típico tem a seguinte estrutura:

  • Cargo.toml: arquivo de configuração do projeto (manifesto). Contém metadados como nome, versão, autores, dependências, etc.
  • src/: diretório onde ficam os arquivos de código-fonte. Por padrão, main.rs (para binários) ou lib.rs (para bibliotecas).
  • .gitignore: arquivo para ignorar a pasta target/ (onde o Cargo coloca os artefatos de build) e outros arquivos gerados.
  • target/: (não aparece até você compilar) contém os binários compilados, dependências e outros artefatos. Não deve ser versionado.

Você pode adicionar mais arquivos .rs dentro de src/ ou criar subdiretórios, como src/bin/ para múltiplos binários. O Cargo segue convenções, então é importante manter a organização.

cargo run e cargo build

Para compilar seu projeto, use cargo build. Isso gera um executável em target/debug/ (ou target/release/ com a flag --release). O Cargo também baixa e compila as dependências listadas no Cargo.toml.

Para compilar e executar em um único passo, use cargo run. Ele compila (se necessário) e depois executa o binário. Exemplo:

cd hello_world
cargo run

Saída esperada:

   Compiling hello_world v0.1.0 (/caminho/para/hello_world)
    Finished dev [unoptimized + debuginfo] target(s) in 0.5s
     Running `target/debug/hello_world`
Hello, world!

Outros comandos úteis: cargo check (verifica se o código compila sem gerar binário) e cargo test (roda testes).

Cargo.toml básico

O Cargo.toml é escrito no formato TOML (Tom's Obvious, Minimal Language). Um exemplo típico:

[package]
name = "hello_world"
version = "0.1.0"
edition = "2021"
authors = ["Seu Nome "]
description = "Um simples programa Hello, world!"

[dependencies]

Seções principais:

  • [package]: metadados do pacote. name e version são obrigatórios. edition especifica a edição do Rust (2021 é a atual).
  • [dependencies]: lista de dependências externas. Cada dependência é especificada como nome = "versão". Exemplo: serde = "1.0".
  • [dev-dependencies]: dependências usadas apenas em testes e exemplos.
  • [build-dependencies]: dependências para scripts de build.

Você também pode adicionar recursos como [profile.release] para otimizações, ou [lib] para configurar uma biblioteca.

Boas práticas e observações finais

Sempre use o Cargo para gerenciar seus projetos Rust, mesmo para scripts pequenos. Ele facilita a adição de dependências, garante builds reproduzíveis e integra-se com ferramentas como rustfmt e clippy. Mantenha o Cargo.toml organizado e versionado (exceto a pasta target/). Lembre-se de que a edição 2021 é a padrão para novos projetos; evite usar edições antigas a menos que necessário.

Referências

Exercícios

  1. Crie um novo projeto Cargo chamado meu_projeto usando o comando cargo new. Verifique a estrutura de pastas gerada e liste os arquivos criados.

    ✓ Resposta: Execute cargo new meu_projeto. Serão criados os arquivos: Cargo.toml, .gitignore e a pasta src/ com main.rs.
  2. No projeto meu_projeto, modifique o arquivo src/main.rs para imprimir "Olá, mundo do Cargo!" e execute o programa com cargo run.

    ✓ Resposta: Altere main.rs para:
    fn main() {
        println!("Olá, mundo do Cargo!");
    }
    Depois execute cargo run no diretório do projeto.
  3. Explique a diferença entre cargo build e cargo run. Qual é a vantagem de usar cargo check?

    ✓ Resposta: cargo build compila o projeto e gera o binário, mas não o executa. cargo run compila e executa. cargo check verifica se o código compila sem gerar o binário, sendo mais rápido para checagens durante o desenvolvimento.
  4. Adicione uma dependência ao Cargo.toml do projeto: a crate rand na versão 0.8. Em seguida, execute cargo build e observe o download da dependência.

    ✓ Resposta: No Cargo.toml, sob [dependencies], adicione rand = "0.8". Depois execute cargo build. O Cargo baixará a crate e suas dependências.
  5. Crie um novo projeto chamado minha_biblioteca usando a flag --lib. Qual a diferença na estrutura gerada em comparação com um projeto binário?

    ✓ Resposta: Execute cargo new --lib minha_biblioteca. A estrutura terá src/lib.rs em vez de main.rs. O Cargo.toml indicará o tipo como library. Não haverá um binário executável.