Nesta aula, vamos escrever nosso primeiro programa em Go: o clássico "Olá, mundo". Embora seja simples, este programa nos permite explorar a estrutura fundamental de um programa Go, entender os conceitos de pacotes e funções, e aprender a executar e compilar nosso código. Além disso, veremos uma ferramenta essencial do ecossistema Go: o gofmt, que ajuda a manter o código padronizado e legível.

Ao final desta aula, você será capaz de criar um programa básico, executá-lo de duas formas diferentes e garantir que seu código esteja bem formatado de acordo com as convenções da linguagem.

Estrutura de um programa

Um programa em Go é composto por um ou mais arquivos de código-fonte com extensão .go. Cada arquivo pertence a um pacote (package), que é uma forma de organizar e reutilizar código. O programa começa a execução a partir de uma função especial chamada main, que deve estar dentro de um pacote também chamado main.

Vejamos a estrutura mínima de um programa Go:

package main

import "fmt"

func main() {
    fmt.Println("Olá, mundo!")
}

Explicando cada parte:

  • package main: declara que este arquivo pertence ao pacote main. Pacotes são a forma de modularizar o código; o pacote main é especial porque define um programa executável.
  • import "fmt": importa o pacote fmt da biblioteca padrão, que contém funções para entrada e saída formatada, como Println.
  • func main(): define a função principal, que é o ponto de entrada do programa. A execução começa aqui.
  • fmt.Println("Olá, mundo!"): chama a função Println do pacote fmt para imprimir uma linha com a mensagem.

Note que o código é organizado de forma limpa e sem ponto e vírgula no final das linhas (o compilador os insere automaticamente). As chaves { } delimitam blocos de código, e a indentação é feita com tabulações (não espaços).

package main e func main

Em Go, todo programa executável deve ter um pacote chamado main e uma função main dentro dele. O pacote main é especial: quando você compila um programa que está no pacote main, o compilador gera um binário executável. Se você tentar compilar um pacote com outro nome sem uma função main, o compilador rejeitará, pois não há ponto de entrada.

A função main não recebe argumentos e não retorna nada. Se você precisar acessar argumentos da linha de comando, use os.Args ou a biblioteca flag. A função main é o ponto de partida; quando ela termina, o programa termina.

Exemplo de um programa com argumentos:

package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println("Argumentos:", os.Args)
}

Mas por enquanto, vamos nos concentrar no básico.

go run e go build

Go fornece duas maneiras principais de executar seu código: go run e go build.

go run compila e executa o programa imediatamente, sem deixar um arquivo binário. É útil durante o desenvolvimento para testar rapidamente. Por exemplo:

$ go run main.go
Olá, mundo!

go build compila o programa e gera um binário executável no diretório atual (com o nome do pacote ou do diretório). Você pode então executar o binário diretamente:

$ go build main.go
$ ./main
Olá, mundo!

No Windows, o executável terá extensão .exe. Você também pode usar go build -o nome_do_binario main.go para especificar o nome do arquivo de saída.

Além disso, go install compila e instala o binário no diretório $GOPATH/bin (ou $GOBIN), permitindo executá-lo de qualquer lugar.

gofmt

Go é conhecido por sua ênfase em código padronizado. A ferramenta gofmt (ou go fmt) formata automaticamente o código-fonte de acordo com as convenções oficiais: indentação com tabs, espaçamento adequado, alinhamento, etc. Isso elimina discussões sobre estilo e garante que todo código Go pareça similar.

Para usar, execute no terminal:

$ gofmt -w main.go

O flag -w escreve as alterações diretamente no arquivo. Sem ele, a saída formatada é exibida no terminal. Você também pode usar go fmt (que é um atalho para gofmt -l -w em pacotes).

Exemplo de código mal formatado:

package main
import "fmt"
func main(){
fmt.Println("Oi")
}

Após gofmt -w, o código se torna:

package main

import "fmt"

func main() {
	fmt.Println("Oi")
}

Note a adição de linhas em branco e a indentação com tab. A maioria dos editores de código pode ser configurada para executar gofmt automaticamente ao salvar. Isso é altamente recomendado.

Boas práticas

Algumas boas práticas para começar:

  • Nomeie os arquivos com letras minúsculas e use underscores se necessário (ex.: meu_programa.go).
  • Mantenha um arquivo main.go no diretório raiz do seu projeto.
  • Use go fmt antes de cada commit para garantir consistência.
  • Evite importar pacotes que não são usados; o compilador Go não permite isso.

Referências

Exercícios

  1. Escreva um programa que imprima seu nome e sua idade, cada um em uma linha separada.

    ✓ Resposta:
    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("João")
        fmt.Println(30)
    }
  2. Modifique o programa do exercício 1 para imprimir as informações em uma única linha, usando uma única chamada de fmt.Println.

    ✓ Resposta:
    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("João", 30)
    }
  3. Compile o programa do exercício 2 usando go build e execute o binário gerado. Qual é o nome do binário? (Responda em texto)

    ✓ Resposta: O binário terá o nome do diretório onde o comando foi executado (ou o nome do arquivo se você usou go build main.go). Por exemplo, se o arquivo se chama main.go e você executou go build main.go, o binário será main (no Linux/macOS) ou main.exe (no Windows).
  4. Use gofmt para formatar o código abaixo e escreva a saída formatada:

    package main
    import "fmt"
    func main(){
    fmt.Println("formatado")}

    ✓ Resposta:
    package main
    
    import "fmt"
    
    func main() {
    	fmt.Println("formatado")
    }
  5. Explique por que o seguinte código não compila e corrija-o:

    package main
    
    func main() {
        fmt.Println("Olá")
    }

    ✓ Resposta: O código não compila porque o pacote fmt não foi importado, mas fmt.Println está sendo usado. Para corrigir, adicione import "fmt":

    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("Olá")
    }