pratica

Configurando o Projeto e Entrada/Saída de Dados (std::io)

Aprenda sobre configurando o projeto e entrada/saída de dados (std::io)

30 min
Aula 2 de 5

🎮 Projeto Prático: Jogo de Adivinhação - Configurando o Projeto e Entrada/Saída de Dados (std::io)

Bem-vindos ao nosso primeiro projeto prático! 🎉 Neste módulo, vamos construir um divertido jogo de adivinhação. Começaremos com os fundamentos: configurar nosso projeto Rust e aprender a interagir com o usuário através da entrada e saída padrão.

Este é o ponto de partida para transformar o conhecimento teórico em algo real e funcional. Prepare-se para codificar! 🚀

🎯 Objetivos da Aula

Ao final desta aula, você será capaz de:

  • Criar um novo projeto Rust utilizando o cargo.
  • Entender a estrutura básica de um projeto Rust.
  • Utilizar o módulo std::io para ler a entrada do usuário.
  • Exibir mensagens no console usando a macro println!.
  • Realizar operações básicas de manipulação de String, como remover espaços em branco.
  • Converter String para outros tipos numéricos, lidando com possíveis erros.

1. 🏗️ Configurando o Projeto com Cargo

O Cargo é o sistema de build e gerenciador de pacotes do Rust. Ele facilita a criação, compilação e gerenciamento de dependências dos seus projetos.

Criando um Novo Projeto

Para iniciar nosso jogo de adivinhação, vamos criar um novo projeto com o cargo.

cargo new guessing_game

Este comando cria um novo diretório chamado guessing_game com a seguinte estrutura básica:

guessing_game/
├── Cargo.toml
└── src/
    └── main.rs
  • Cargo.toml: Este é o arquivo de manifesto do seu projeto. Ele contém metadados sobre seu projeto (nome, versão, autor) e lista suas dependências. É como o package.json do Node.js ou o pom.xml do Maven.
  • src/main.rs: Este é o arquivo fonte principal do seu projeto. É aqui que o Rust procura pelo ponto de entrada do seu programa (a função main).

Executando o Projeto Inicial

Você pode compilar e executar seu projeto recém-criado com:

cd guessing_game
cargo run

Você deverá ver a saída:

Hello, world!

Isso significa que seu ambiente está configurado corretamente e seu primeiro projeto Rust está funcionando! ✨


2. 🗣️ Entrada e Saída de Dados (std::io)

A interação com o usuário é fundamental para qualquer jogo. Em Rust, o módulo std::io (Input/Output) nos fornece as ferramentas necessárias para ler a entrada do teclado e exibir mensagens na tela.

Imprimindo Mensagens com println!

Já vimos println! em ação. É uma macro (note o !) usada para imprimir texto no console.

fn main() {
    println!("Adivinhe o número!"); // Imprime uma string literal
    let numero = 42;
    println!("O número é: {}", numero); // Imprime com um placeholder
}

Lendo a Entrada do Usuário com std::io::stdin

Para ler o que o usuário digita, usamos std::io::stdin(). Vamos ver um exemplo básico:

use std::io; // Importamos o módulo `io`
 
fn main() {
    println!("Adivinhe o número!");
    println!("Por favor, digite seu palpite.");
 
    let mut palpite = String::new(); // 1. Criamos uma String mutável e vazia
 
    io::stdin() // 2. Obtemos um "handle" para a entrada padrão
        .read_line(&mut palpite) // 3. Lemos a linha e a colocamos na String `palpite`
        .expect("Falha ao ler a linha"); // 4. Lidamos com erros (explicaremos isso!)
 
    println!("Você palpitou: {}", palpite); // 5. Imprimimos o palpite do usuário
}

Vamos detalhar cada parte:

  1. let mut palpite = String::new();:
    • String::new() cria uma nova instância vazia do tipo String, que é uma string mutável e alocada na heap.
    • Usamos mut para indicar que a variável palpite pode ser alterada. Strings em Rust são UTF-8.
  2. io::stdin():
    • Retorna uma instância de std::io::Stdin, que representa o handle para a entrada padrão do terminal.
  3. .read_line(&mut palpite):
    • Este método lê a entrada do usuário até encontrar uma quebra de linha (Enter) e a anexa à string fornecida.
    • Ele espera uma referência mutável (&mut palpite) para que possa modificar a string.
    • Importante: read_line retorna um Result, que é um tipo enumerado que representa sucesso (Ok) ou falha (Err).
  4. .expect("Falha ao ler a linha"):
    • Result é um tipo fundamental em Rust para tratamento de erros. Ele tem duas variantes: Ok(T) (sucesso, contendo um valor T) e Err(E) (erro, contendo um valor E).
    • O método .expect() é uma maneira simples (e muitas vezes rude em produção, mas útil para exemplos) de lidar com um Result. Se o Result for Err, ele causa um panic! (o programa trava) e imprime a mensagem fornecida. Se for Ok, ele retorna o valor contido em Ok.
    • No caso de read_line, ele retorna o número de bytes lidos em Ok.

Manipulando a Entrada: Removendo Espaços e Quebras de Linha

Quando o usuário digita "5" e pressiona Enter, a string palpite não conterá apenas "5", mas sim "5\n" (ou "5\r\n" no Windows). Precisamos remover esses caracteres de quebra de linha.

O método trim() de String é perfeito para isso:

// ... (código anterior)
 
io::stdin()
    .read_line(&mut palpite)
    .expect("Falha ao ler a linha");
 
let palpite = palpite.trim(); // `trim()` retorna uma nova `&str` sem espaços em branco no início/fim
 
println!("Você palpitou: {}", palpite);

Observe que trim() retorna uma &str (slice de string), não uma String. Se você precisar de uma String novamente, pode usar .to_string().

Convertendo a Entrada para um Número

Nosso jogo de adivinhação precisará comparar o palpite do usuário (uma String) com um número secreto. Para isso, precisamos converter a String para um tipo numérico, como u32 (inteiro de 32 bits sem sinal).

O método parse() de &str pode fazer isso:

use std::io;
 
fn main() {
    println!("Adivinhe o número!");
    println!("Por favor, digite seu palpite.");
 
    let mut palpite = String::new();
    io::stdin().read_line(&mut palpite).expect("Falha ao ler a linha");
 
    // Convertemos a String para u32
    let palpite: u32 = palpite.trim().parse().expect("Por favor, digite um número!");
 
    println!("Você palpitou: {}", palpite);
}
  • palpite.trim().parse():
    • parse() também retorna um Result. Se a string não puder ser convertida para o tipo especificado (por exemplo, "abc" para u32), ele retornará um Err.
    • O tipo u32 é inferido pelo Rust a partir da anotação let palpite: u32 = ....
  • .expect("Por favor, digite um número!"):
    • Novamente, usamos expect para lidar com o Result retornado por parse(). Se o usuário digitar algo que não seja um número, o programa entrará em pânico com a mensagem fornecida.

3. 📚 Exemplo de Código Oficial (Adaptado do The Rust Book)

O trecho de código abaixo é uma adaptação do capítulo "Programming a Guessing Game" do The Rust Book, mostrando como ler a entrada do usuário e convertê-la para um número.

use std::io; // Importa o módulo `io` da biblioteca padrão
 
fn main() {
    println!("Adivinhe o número!"); // Imprime uma mensagem de boas-vindas
 
    println!("Por favor, insira seu palpite."); // Solicita a entrada do usuário
 
    let mut palpite = String::new(); // Cria uma nova String mutável para armazenar o palpite
 
    // Lê a linha de entrada do usuário e armazena em `palpite`
    // `.expect()` lida com o erro caso a leitura falhe
    io::stdin()
        .read_line(&mut palpite)
        .expect("Falha ao ler a linha");
 
    // Converte a String `palpite` para um número inteiro de 32 bits sem sinal (`u32`)
    // `.trim()` remove espaços em branco e quebras de linha
    // `.parse()` tenta converter a string para o tipo numérico especificado
    // `.expect()` lida com o erro caso a conversão falhe (ex: se o usuário digitar texto)
    let palpite: u32 = palpite
        .trim()
        .parse()
        .expect("Por favor, digite um número!");
 
    // Imprime o palpite do usuário
    println!("Você palpitou: {}", palpite);
}

Este código é a base para a interação inicial do nosso jogo!


4. 🚀 Exercícios/Desafios

É hora de colocar a mão na massa! Siga os passos abaixo para construir a parte inicial do seu jogo de adivinhação.

Tarefas:

  • Crie um novo projeto Rust chamado guessing_game usando cargo new.
  • Abra o arquivo src/main.rs.
  • Modifique a função main para imprimir a mensagem de boas-vindas: "Adivinhe o número!".
  • Adicione uma linha para solicitar ao usuário que insira seu palpite: "Por favor, digite seu palpite.".
  • Declare uma variável mutável do tipo String para armazenar a entrada do usuário.
  • Use std::io::stdin().read_line() para ler a entrada do usuário e armazene-a na sua variável String. Não se esqueça de usar .expect() para lidar com possíveis erros de leitura.
  • Imprima a entrada do usuário de volta no console, formatando a saída para mostrar "Você palpitou: [palpite do usuário]".
  • Desafio Extra: Modifique o código para que, após ler a entrada, você use trim() e parse() para tentar converter o palpite do usuário para um u32. Use .expect() para lidar com falhas de conversão (por exemplo, se o usuário digitar texto). Imprima o número convertido.

Dicas:

  • Lembre-se de importar use std::io; no início do seu arquivo.
  • Use cargo run para testar seu código a cada etapa.
  • Se encontrar erros, leia as mensagens do compilador Rust cuidadosamente; elas são muito úteis!

5. 📝 Resumo e Próximos Passos

Nesta aula, você deu os primeiros passos cruciais na construção do seu jogo de adivinhação:

  • Aprendemos a iniciar um projeto Rust com cargo new.
  • Exploramos a estrutura básica de um projeto Rust.
  • Dominamos o uso de println! para saída de texto.
  • Utilizamos std::io::stdin().read_line() para capturar a entrada do usuário.
  • Vimos como trim() remove espaços em branco e parse() converte strings em números, e como .expect() nos ajuda a lidar com os Results retornados por essas operações.

No próximo capítulo, vamos adicionar a lógica central do jogo: gerar um número aleatório e comparar o palpite do usuário com esse número. Prepare-se para aprender sobre números aleatórios e estruturas de controle de fluxo! 🎲

Até lá, continue praticando e experimentando com o código!

© 2025 Escola All Dev. Todos os direitos reservados.

Configurando o Projeto e Entrada/Saída de Dados (std::io) - Curso gratuito de Rust: A linguagem mais amada | escola.all.dev.br