Paquetes y Módulos
## Objetivos de Aprendizaje
- Comprender los paquetes de Go
- Crear y usar módulos
- Importar paquetes correctamente
- Organizar código efectivamente
- Trabajar con el archivo go.mod
## Paquetes
### ¿Qué es un Paquete?
Un paquete es una colección de archivos fuente Go en el mismo directorio.
### Declaración de Paquete
```go
package main // Paquete ejecutable
package utils // Paquete de biblioteca
```
### Nombres de Paquetes
```go
package main // Ejecutable
package math // Biblioteca (funciones matemáticas)
```
## Estructura del Proyecto
### Diseño Estándar
```text
myproject/
├── go.mod
├── main.go
├── utils/
│ └── helpers.go
└── models/
└── user.go
```
### Nombres de Paquetes Coinciden con Directorios
```text
utils/helpers.go -> package utils
models/user.go -> package models
```
## Módulos
### ¿Qué es un Módulo?
Un módulo es una colección de paquetes versionados juntos.
### Crear un Módulo
```bash
go mod init example.com/myproject
```
### Archivo go.mod
```text
module example.com/myproject
go 1.21
require (
github.com/some/pkg v1.2.3
)
```
## Importaciones
### Importación Básica
```go
import "fmt"
func main() {
fmt.Println("Hola")
}
```
### Múltiples Importaciones
```go
import (
"fmt"
"math"
"strings"
)
func main() {
fmt.Println(math.pi)
fmt.Println(strings.ToUpper("hello"))
}
```
### Importación con Alias
```go
import (
f "fmt" // Alias
m "math" // Alias
)
func main() {
f.Println(m.pi)
}
```
### Importación Dot
```go
import . "fmt" // Evitar: contamina el namespace
func main() {
Println("Hola") // Sin prefijo
}
```
### Importación Blank
```go
import _ "database/sql" // Solo registra el driver
```
## Creando Paquetes
### utils/helpers.go
```go
package utils
func Reverse(s string) string {
runes := []rune(s)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
}
func UpperCase(s string) string {
return strings.ToUpper(s)
}
```
### main.go
```go
package main
import (
"fmt"
"example.com/myproject/utils"
)
func main() {
fmt.Println(utils.Reverse("hello"))
fmt.Println(utils.UpperCase("hello"))
}
```
## Reglas de Visibilidad
### Exportado vs No Exportado
```go
package utils
const MaxSize = 100 // Exportado (mayúscula)
const minSize = 10 // No exportado (minúscula)
func PublicFunc() {} // Exportado
func privateFunc() {} // No exportado
```
### Acceso desde Fuera
```go
import "example.com/myproject/utils"
utils.MaxSize // OK
utils.PublicFunc() // OK
// utils.minSize // ERROR: no accesible
// utils.privateFunc() // ERROR: no accesible
```
## Función init
### Ejecución Automática
```go
package utils
var config string
func init() {
config = "default"
}
```
### Múltiples Funciones init
```go
package main
func init() {
fmt.Println("Primera init")
}
func init() {
fmt.Println("Segunda init")
}
```
### Orden de init
1. Paquetes importados se inicializan primero
2. Variables a nivel de paquete se inicializan
3. Funciones init() se ejecutan en orden de declaración
## Paquetes de la Biblioteca Estándar
### Importaciones Comunes
```go
import "fmt" // E/S formateada
import "os" // Sistema operativo
import "io" // Primitivas de E/S
import "bufio" // E/S con buffer
import "strings" // Utilidades de cadena
import "strconv" // Conversión de cadena
import "time" // Operaciones de tiempo
import "math" // Funciones matemáticas
import "log" // Registro
import "errors" // Manejo de errores
```
### net/http
```go
import "net/http"
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hola"))
})
http.ListenAndServe(":8080", nil)
}
```
### encoding/json
```go
import "encoding/json"
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
p := Person{Name: "Alice", Age: 30}
jsonBytes, _ := json.Marshal(p)
fmt.Println(string(jsonBytes))
}
```
## Paquetes Externos
### go get
```bash
go get github.com/gin-gonic/gin
go get github.com/stretchr/testify
```
### Especificación de Versión
```text
require (
github.com/gin-gonic/gin v1.9.1
github.com/stretchr/testify v1.8.4
)
```
### go.sum
Se genera y rastrea automáticamente.
## Comandos de Módulo
### Comandos Comunes
```bash
go mod init example.com/project # Inicializar módulo
go mod tidy # Limpiar dependencias
go mod download # Descargar dependencias
go mod graph # Mostrar gráfico de dependencias
go mod why github.com/pkg # Explicar por qué dependencia
```
### go mod tidy
```bash
# Elimina dependencias no usadas
# Añade dependencias faltantes
# Actualiza go.mod y go.sum
go mod tidy
```
## Vendoring
### Crear Vendor
```bash
go mod vendor
```
### Estructura de Directorios
```text
project/
├── go.mod
├── go.sum
├── vendor/
│ └── github.com/
│ └── pkg/
│ └── *.go
└── main.go
```
### Usar Vendor
```bash
go build -mod=vendor
```
## Probando Paquetes
### Prueba Básica
```go
package utils
func Add(a, b int) int {
return a + b
}
```
### utils_test.go
```go
package utils
import "testing"
func TestAdd(t *testing.T) {
result := Add(2, 3)
if result != 5 {
t.Errorf("Add(2, 3) = %d, want 5", result)
}
}
```
### Ejecutar Pruebas
```bash
go test ./... # Ejecutar todas las pruebas
go test -v ./... # Salida verbosa
go test -cover ./... # Mostrar cobertura
```
## Consejos de Organización de Código
### Un Módulo por Proyecto
```text
myproject/
├── go.mod
├── cmd/
│ └── app/
│ └── main.go
├── internal/
│ ├── handlers/
│ ├── models/
│ └── services/
├── pkg/
│ └── utils/
└── api/
```
### Paquete internal
Los paquetes llamados `internal` solo son importables por directorios padres.
```text
myproject/
├── internal/
│ └── utils/
│ └── helpers.go
└── cmd/
└── app/
└── main.go // Puede importar internal/utils
```
## Resumen
- Los paquetes agrupan archivos fuente Go relacionados
- Los módulos son colecciones versionadas de paquetes
- `go.mod` define nombre del módulo y dependencias
- Los identificadores exportados comienzan con mayúscula
- `init()` se ejecuta automáticamente antes de main
- Usar `go get` para añadir dependencias
- `go mod tidy` gestiona dependencias
- Los archivos de prueba terminan en `_test.go`
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →