Como ler da entrada padrão em Go: do iniciante ao profissional
Você já se perguntou como fazer seu programa Go "ouvir" o usuário? Como escrever um utilitário que aceita comandos do console, ou uma ferramenta CLI interativa? Se sim, você veio ao lugar certo. Hoje vamos abordar a leitura da entrada padrão (stdin) em Go — com o máximo de detalhes possível.
Este tópico é um verdadeiro sucesso no Stack Overflow. A pergunta "How can I read from standard input in the console?" acumulou milhares de visualizações. E não é à toa: a entrada padrão é a base sem a qual nenhum projeto sério em Go sobrevive. Vamos adaptar esta questão para o público de língua portuguesa e transformá-la em um tutorial completo.
Neste artigo, você aprenderá:
- O que é
os.Stdine como trabalhar com ele - Como usar
bufio.Scannerpara leitura linha por linha - Por que
fmt.Scané uma faca de dois gumes - Como ler arquivos inteiros do stdin
- Segredos de tratamento de erros e desempenho
Vamos lá!
O que é stdin e por que você precisa dele em Go?
A entrada padrão (stdin) é um fluxo de dados que seu programa recebe do console ou de outro processo. Em Go, ela é representada pela variável os.Stdin do tipo *os.File. É o portal através do qual os dados entram no seu programa.
Por que você precisa disso? Imagine:
- Você está escrevendo um utilitário CLI que processa a entrada do usuário
- Você está criando um analisador de logs que lê dados via pipe (
cat log.txt | myapp) - Você precisa implementar entrada interativa com dicas
Go, sendo uma linguagem para programação de sistemas, oferece ferramentas elegantes para trabalhar com stdin. Vamos analisá-las em ordem.
Método 1: bufio.Scanner — o rei da leitura linha por linha
A maneira mais popular e recomendada de ler do stdin em Go é usando bufio.Scanner. É simples, eficiente e resolve 90% dos problemas.
Aqui está um exemplo clássico:
package main
import ( "bufio" "fmt" "os")
func main() { scanner := bufio.NewScanner(os.Stdin) fmt.Println("Digite o texto (Ctrl+D para finalizar):") for scanner.Scan() { line := scanner.Text() fmt.Println("Você digitou:", line) } if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "Erro de leitura:", err) }}Como funciona?
bufio.NewScanner(os.Stdin)— cria um scanner que lê da entrada padrãoscanner.Scan()— retornatrueenquanto houver dados (por padrão, até o caractere de nova linha)scanner.Text()— retorna a linha atual sem o caractere- O loop é interrompido no
EOF(Ctrl+D no Linux/Mac, Ctrl+Z no Windows)
Este código é a base para qualquer entrada de console Go. Ele funciona perfeitamente com pipes e entrada interativa.
Personalização do Scanner
Por padrão, o Scanner divide a entrada por linhas. Mas você pode alterar isso:
// Leitura por palavrasscanner.Split(bufio.ScanWords)
// Leitura por bytesscanner.Split(bufio.ScanBytes)
// Leitura por caracteres (runas)scanner.Split(bufio.ScanRunes)Você também pode definir seu próprio divisor — por exemplo, para CSV ou separadores personalizados. Mas isso já é assunto para outro artigo.
Método 2: fmt.Scan — rápido e sujo
Se você precisa inserir um único valor — um número, uma string ou várias variáveis — fmt.Scan vem em seu socorro. É como o scanf em C, só que