📦 Módulos y paquetes en Go
go mod init, go.mod y go.sum, dependencias y semver, GOPATH vs modules, estructura de proyecto profesional, exportación y la librería estándar clave.
Módulos y paquetes en Go
Un módulo es la unidad de distribución y versionado de Go: agrupa paquetes y declara sus dependencias. Desde Go 1.11 el sistema de modules es el estándar, reemplazando al antiguo GOPATH. Dominar módulos y paquetes es lo que separa un script suelto de un proyecto profesional.
¿Qué es un paquete?
Un paquete es una colección de archivos .go en el mismo directorio que comparten un package y un namespace. Es la unidad de compilación y reutilización.
package maingenera un ejecutable (debe tenerfunc main).- Cualquier otro nombre genera una biblioteca importable.
// archivo: greeting/greeting.go
package greeting
// Saludar devuelve un saludo. Exportado: empieza por mayúscula.
func Saludar(nombre string) string {
return "Hola, " + nombre
}
Exportar: mayúsculas
En Go, la visibilidad se controla con la primera letra:
- Mayúscula → exportado (visible fuera del paquete):
Saludar,Config. - Minúscula → privado (solo dentro del paquete):
saludar,config.
package greeting
var saludoPrivado = "Hola" // no accesible desde fuera
var SaludoPublico = "Hola!" // accesible desde fuera
💡 No existe
public/private/protected. Si empieza por mayúscula, es público; si no, privado. Simple y contundente.
Inicializar un módulo
go mod init crea el go.mod con el path del módulo (normalmente tu repo: github.com/usuario/proyecto):
go mod init github.com/tuusuario/miapp
Esto genera:
module github.com/tuusuario/miapp
go 1.22
⚠️ Elige bien el path del módulo desde el principio: renombrarlo después obliga a actualizar todos los imports. Para proyectos locales sin publicar sirve cualquier nombre, pero la convención es el repo.
go.mod y go.sum
- go.mod — declara el módulo, la versión de Go y las dependencias directas e indirectas.
- go.sum — contiene los checksums (hashes) de cada dependencia para garantizar integridad y reproducibilidad. No lo edites a mano.
module github.com/tuusuario/miapp
go 1.22
require github.com/gorilla/mux v1.8.1
require (
golang.org/x/sync v0.7.0 // indirect
)
// indirect— dependencia no importada directamente (dependencia de una dependencia).
Gestión de dependencias
Los comandos modernos de Go gestionan el go.mod automáticamente:
| Comando | Acción |
|---|---|
go get paquete@version |
Añade o actualiza una dependencia |
go get paquete@latest |
Última versión |
go get -u ./... |
Actualiza todas |
go add paquete |
Añade (nuevo, Go 1.22+) |
go mod tidy |
Añade/elimina dependencias según lo importado |
go mod download |
Descarga a la caché local |
# añadir una dependencia concreta
go get github.com/gorilla/mux@v1.8.1
# limpiar: quita lo no usado, añade lo faltante
go mod tidy
💡 Corre
go mod tidyantes de commitear. Mantienego.mod/go.sumconsistentes y elimina dependencias huérfanas.
Versiones semver
Go sigue Semantic Versioning (MAYOR.MENOR.PARCHE):
- MAYOR — cambios incompatibles (
v2,v3…). - MENOR — nuevas funciones retrocompatibles (
v1.8). - PARCHE — correcciones (
v1.8.1).
Los prefijos v son obligatorios: v1.8.1. Para versiones mayores a 1, el path del módulo suele incluir /v2.
import "github.com/usuario/lib/v2" // módulo en su v2
GOPATH vs modules
Antes de modules, todo vivía bajo $GOPATH/src y las dependencias se copiaban en $GOPATH/pkg/mod. Eso impedía versiones por proyecto.
| Aspecto | GOPATH | Modules (moderno) |
|---|---|---|
| Ubicación del código | fijo en $GOPATH/src |
cualquier carpeta |
| Versiones | única global | por proyecto en go.mod |
| Resolución | go get global |
go get/go mod tidy local |
| Integridad | no verificada | go.sum |
| Estado | obsoleto | estándar desde Go 1.16 |
💡
go env GOPATHsigue existiendo para la caché de módulos, pero ya no defines tu código ahí.go envte muestra todas las variables.
Estructura de proyecto profesional
Go recomienda un layout estándar que separa lo ejecutable de lo interno:
miapp/
├── cmd/
│ ├── server/
│ │ └── main.go # punto de entrada del ejecutable server
│ └── cli/
│ └── main.go # otro ejecutable cli
├── internal/
│ └── services/
│ └── user.go # código interno, no importable desde fuera del módulo
├── pkg/
│ └── utils/
│ └── strings.go # código público reutilizable
├── go.mod
└── go.sum
cmd/— un subdirectorio por ejecutable, cada uno con sumain.go.internal/— código privado del proyecto: Go impide importarlo desde fuera del módulo. Regla de oro para APIs internas.pkg/— código público que otros proyectos pueden importar.
⚠️
internal/no es un capricho: el compilador bloquea la importación de paquetes dentro deinternal/desde fuera del módulo. Úsalo para aislar implementación.
Importar paquetes
Imports por path del módulo + ruta relativa:
package main
import (
"fmt"
"github.com/tuusuario/miapp/internal/services"
"github.com/tuusuario/miapp/pkg/utils"
)
func main() {
fmt.Println(utils.Capitalizar("hola"))
services.CrearUsuario()
}
- Los imports se agrupan: estándar primero, luego terceros/propios (con
gofmt/goimports). - Importar y no usar = error de compilación.
Paquetes estándar clave
La librería estándar de Go es enorme. Estos son los que usarás casi a diario:
| Paquete | Qué hace | Ejemplo |
|---|---|---|
fmt |
formato y salida | fmt.Sprintf("%s", x) |
strings |
manipular strings | strings.Split, strings.Join |
strconv |
convertir strings↔números | strconv.Atoi |
time |
fechas y tiempos | time.Now(), time.Sleep |
os |
sistema operativo, args, env | os.Getenv, os.Args |
io |
flujos de lectura/escritura | io.Reader, io.Copy |
net/http |
servidor y cliente HTTP | http.Get |
encoding/json |
serializar JSON | json.Marshal |
sort |
ordenar slices | sort.Ints |
errors |
crear y combinar errores | errors.New, errors.Is |
sync |
primitivas de concurrencia | sync.WaitGroup |
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
)
func demo() {
n, _ := strconv.Atoi("42") // string -> int
partes := strings.Split("a,b,c", ",") // ["a","b","c"]
fecha := time.Now().Format("2006-01-02")
datos, _ := json.Marshal(map[string]int{"a": 1})
fmt.Println(n, partes, fecha, string(datos))
}
Herramientas: gofmt, go vet, go build
# formatea el código según el estilo oficial (obligatorio en la comunidad)
gofmt -w .
# analizador estático: detecta bugs y código sospechoso
go vet ./...
# compila sin generar binario (verifica que todo compila)
go build ./...
# ejecuta el paquete main
go run ./cmd/server
# compila e instala en GOBIN/GOPATH/bin
go install ./...
gofmt— normaliza sangría, espaciado e imports. Todos los proyectos Go pasan por él.go vet— señala errores sutiles (printf incorrecto, copias de locks, etc.). Corre en CI.go buildvsgo run—buildcompila a binario;runcompila y ejecuta en memoria.
💡 Instala el formateo automático en tu editor (on-save).
go vet ./...debería correr en cada push o PR.
Cross-compile con GOOS y GOARCH
Go compila fácilmente para otras plataformas con variables de entorno. Compila sin dependencias nativas:
| Variable | Valores | Significado |
|---|---|---|
GOOS |
linux, darwin, windows |
sistema operativo objetivo |
GOARCH |
amd64, arm64, 386 |
arquitectura objetivo |
# binario de Linux x86-64 desde Windows
GOOS=linux GOARCH=amd64 go build ./...
# binario de Windows ARM64
GOOS=windows GOARCH=arm64 go build ./...
# compilar con nombre de salida
GOOS=linux GOARCH=amd64 go build -o server-linux ./cmd/server
⚠️ En PowerShell (Windows) no funcionan los prefijos
VAR=valorde Unix. Usa$env:GOOS="linux"; $env:GOARCH="amd64"; go build ./...y luegoRemove-Item Env:GOOS.
Cheatsheet
| Necesitas… | Usa… |
|---|---|
| Crear módulo | go mod init <path> |
| Añadir dependencia | go get <paquete>@<versión> |
| Limpiar dependencias | go mod tidy |
| Código privado | carpeta internal/ |
| Ejecutables | carpeta cmd/ |
| Exportar | mayúscula inicial |
| Formatear | gofmt -w . |
| Analizar | go vet ./... |
| Cross-compile | GOOS / GOARCH |
Para profundizar
- go.dev — Managing dependencies: guía oficial de módulos.
- Go Modules Reference: referencia completa del formato go.mod.
- Standard Go Project Layout: el layout profesional más usado.
- A Tour of Go — Packages: paquetes e imports en el tour oficial.
- pkg.go.dev: documentación de todos los paquetes estándar.