Estrutura e Gerenciamento de Projetos em Go

  1. Módulos: a unidade básica de um projeto Go

Em Go, a menor unidade de gerenciamento de código é o módulo. Um módulo é simplesmente um diretório que contém um arquivo go.mod, responsável por armazenar o caminho do módulo, a versão da linguagem e as dependências diretas.

Para criar um novo módulo, execute:

mkdir minicurso-go && cd minicurso-go
go mod init minicurso

Após adicionar um pacote interno, a estrutura ficará semelhante a:

minicurso-go
├── go.mod
└── soma
    └── somador.go

O arquivo go.mod gerado terá, inicialmente, este conteúdo:

module minicurso

go 1.25.0
  1. Pacotes e organização interna

Dantro de um módulo, o código é dividido em pacotes. Um pacote agrupa um ou mais arquivos .go que residem no mesmo diretório e declaram o mesmo nome de pacote. Por convenção, o nome do pacote coincide com o nome da pasta.

É possível ter um pacote de teste exclusivo em um diretório, desde que seu nome seja <pasta>_test e os arquivos terminem com _test.go. Exemplo:

minicurso-go
├── go.mod
├── aritmetica
│   ├── multiplicar.go
│   └── multiplicar_test.go
└── principal.go

Conteúdo de multiplicar.go:

package aritmetica

func Multiplicar(a, b int) int {
    return a * b
}

Conteúdo de multiplicar_test.go, usando o pacote de teste externo:

package aritmetica_test

import (
    "testing"
    "minicurso/aritmetica"
)

func TestMultiplicar(t *testing.T) {
    esperado := 42
    obtido := aritmetica.Multiplicar(6, 7)
    if obtido != esperado {
        t.Errorf("Multiplicar(6, 7) = %d; esperado %d", obtido, esperado)
    }
}
  1. Workspace: coordenando múltiplos módulos

Quando um projeto cresce, é comum dividi-lo em vários módulos. O workspace permite agrupar esses módulos e manter as dependências entre eles sem precisar publicar cada um em repositórios remotos.

Considere a seguinte estrutura:

sistema
├── go.work
├── utilitarios
│   ├── go.mod
│   └── texto
│       └── texto.go
└── app
    ├── go.mod
    └── main.go

Para criar o workspace a partir dos dois módulos locais, use:

go work init utilitarios app

Isso gera o arquivo go.work:

go 1.25.0

use (
    ./utilitarios
    ./app
)

Com isso, o módulo app pode importar pacotes do módulo utilitarios naturalmente, desde que o workspace esteja ativo.

  1. Importando pacotes

4.1 Entre pacotes do mesmo módulo

Dentro de um mesmo módulo, a importação usa o caminho completo formado por nome-do-módulo/caminho-do-pacote, não caminhos relatiovs.

Estrutura de exemplo:

minicurso
├── go.mod
├── operacoes
│   └── soma.go
└── verificacao
    └── soma_test.go

soma.go:

package operacoes

func Somar(a, b int) int {
    return a + b
}

soma_test.go:

package verificacao

import (
    "testing"
    "minicurso/operacoes"
)

func TestSomar(t *testing.T) {
    total := operacoes.Somar(10, 20)
    if total != 30 {
        t.Errorf("Somar(10, 20) = %d; esperado 30", total)
    }
}

4.2 Entre módulos locais

Para que um módulo utilize pacotes de outro módulo local, basta que ambos estejam declarados no go.work:

go 1.25.0

use (
    ./utilitarios
    ./app
)

Dentro de app/main.go, a importação ocorre normalmente:

package main

import (
    "fmt"
    "utilitarios/texto"
)

func main() {
    fmt.Println(texto.Maiusculas("olá, workspace"))
}

4.3 De repositórios remotos

Para adicionar uma biblioteca externa, declare-a em go.mod com a diretiva require:

module app

go 1.25.0

require github.com/pborman/uuid v1.2.1

Em seguida, baixe a dependência:

go get -u github.com/pborman/uuid

Se houver dificuldades de rede, configure um proxy mirror antes de tentar novamente:

go env -w GOPROXY=https://goproxy.cn,direct

Tags: go Golang Go Modules Go Workspaces Dependency Management

Publicado em 6-30 05:23