Paquete builtin en Go
El paquete builtin en Go no es un paquete tradicional que requiera importación. Representa las funciones, tipos y constantes predefinidas en el lenguaje Go que están disponibles globalmente sin necesidad de importación.
1. Funciones Predefinidas
1.1 append
Agrega elementos a un slice y devuelve el slice resultante.
func ejemplosAppend() {
// Ejemplo básico
slice := []int{1, 2}
slice = append(slice, 3, 4)
// Append con múltiples elementos
extras := []int{5, 6, 7}
slice = append(slice, extras...)
// Append con capacidad pre-reservada
slice = make([]int, 0, 10)
for i := 0; i < 5; i++ {
slice = append(slice, i)
}
// Append en slices de interfaces
var mixed []any
mixed = append(mixed, 42, "hola", true)
}
1.2 cap y len
Funciones para manejar capacidad y longitud de estructuras de datos.
func ejemplosCapLen() {
// Arrays
arr := [5]int{1, 2, 3}
fmt.Printf("Array - len: %d, cap: %d\n", len(arr), cap(arr))
// Slices
slice := make([]int, 3, 10)
fmt.Printf("Slice - len: %d, cap: %d\n", len(slice), cap(slice))
// Strings
str := "hola"
fmt.Printf("String - len: %d\n", len(str))
// Canales
ch := make(chan int, 5)
fmt.Printf("Canal - len: %d, cap: %d\n", len(ch), cap(ch))
}
1.3 copy
Copia elementos entre slices.
func ejemplosCopy() {
// Copia básica
src := []int{1, 2, 3, 4, 5}
dst := make([]int, len(src))
copied := copy(dst, src)
fmt.Printf("Copiados: %d elementos\n", copied)
// Copia parcial
dst2 := make([]int, 3)
copied = copy(dst2, src)
fmt.Printf("Copiados parcialmente: %d elementos\n", copied)
// Copia con solapamiento
slice := []int{1, 2, 3, 4, 5}
copy(slice[2:], slice[1:])
fmt.Println("Después del solapamiento:", slice)
}
1.4 delete y make
Operaciones con mapas y creación de estructuras de datos.
func ejemplosDeleteMake() {
// Mapas
m := make(map[string]int)
m["uno"] = 1
m["dos"] = 2
delete(m, "uno")
// Slices
slice := make([]int, 5, 10)
// Canales
ch := make(chan string, 5)
// Mapas con tipo personalizado
type Persona struct {
Nombre string
Edad int
}
personas := make(map[string]Persona)
}
1.5 panic y recover
Manejo de errores y recuperación.
func ejemplosPanicRecover() {
// Ejemplo básico
defer func() {
if r := recover(); r != nil {
fmt.Printf("Recuperado de: %v\n", r)
}
}()
// Panic con error personalizado
type ErrorPersonalizado struct {
Mensaje string
Codigo int
}
// Función que puede entrar en pánico
procesarDatos := func(data []int) {
if len(data) == 0 {
panic(ErrorPersonalizado{
Mensaje: "Datos vacíos",
Codigo: 500,
})
}
}
procesarDatos([]int{}) // Esto causará pánico
}
2. Tipos Predefinidos
2.1 Tipos Numéricos
func ejemplosTiposNumericos() {
// Enteros
var (
a int = 42
b int8 = 127
c int16 = 32767
d int32 = 2147483647
e int64 = 9223372036854775807
)
// Enteros sin signo
var (
f uint = 42
g uint8 = 255
h uint16 = 65535
i uint32 = 4294967295
j uint64 = 18446744073709551615
k uintptr = uintptr(unsafe.Pointer(&a))
)
// Punto flotante
var (
l float32 = 3.14159
m float64 = 3.14159265359
)
// Complejos
var (
n complex64 = 1 + 2i
o complex128 = 1.5 + 2.5i
)
}
2.2 Tipos Compuestos
func ejemplosTiposCompuestos() {
// Arrays
var matriz [3][4]int
// Slices
slice := []string{"a", "b", "c"}
// Mapas
mapa := map[string]any{
"nombre": "Juan",
"edad": 30,
"activo": true,
}
// Canales
ch1 := make(chan int) // Canal sin buffer
ch2 := make(chan int, 10) // Canal con buffer
ch3 := make(chan<- int) // Canal solo envío
ch4 := make(<-chan int) // Canal solo recepción
}
3. Constantes Predefinidas
3.1 iota
func ejemplosIota() {
const (
Domingo = iota
Lunes
Martes
Miércoles
Jueves
Viernes
Sábado
)
const (
_ = iota // 0
KB float64 = 1 << (10 * iota) // 1 << 10
MB // 1 << 20
GB // 1 << 30
TB // 1 << 40
)
const (
Norte = 1 << iota // 1
Este // 2
Sur // 4
Oeste // 8
)
}
4. Ejemplos Prácticos
4.1 Manejo de Colecciones
func ejemplosColecciones() {
// Slice dinámico
datos := make([]int, 0, 10)
for i := 0; i < 20; i++ {
datos = append(datos, i)
fmt.Printf("len=%d cap=%d %v\n", len(datos), cap(datos), datos)
}
// Mapa con valores compuestos
type Producto struct {
Nombre string
Precio float64
Stock int
}
inventario := make(map[string]Producto)
inventario["A001"] = Producto{"Laptop", 999.99, 10}
inventario["A002"] = Producto{"Mouse", 29.99, 50}
// Eliminación segura
if _, existe := inventario["A003"]; existe {
delete(inventario, "A003")
}
}
4.2 Manejo de Errores Avanzado
func ejemploErroresAvanzados() {
type ErrorOperacion struct {
Operacion string
Err error
}
func (e *ErrorOperacion) Error() string {
return fmt.Sprintf("error en %s: %v", e.Operacion, e.Err)
}
// Función que usa panic y recover
procesarOperacion := func(operacion string) (err error) {
defer func() {
if r := recover(); r != nil {
err = &ErrorOperacion{
Operacion: operacion,
Err: fmt.Errorf("%v", r),
}
}
}()
// Simular operación que puede fallar
if operacion == "" {
panic("operación inválida")
}
return nil
}
}
5. Mejores Prácticas
- Uso de append
- Pre-reserva capacidad cuando conoces el tamaño final
- Usa append(…) para concatenar slices
- Considera la capacidad al hacer operaciones en batch
- Manejo de Errores
- Usa panic solo para errores irrecuperables
- Implementa recover en funciones críticas
- Propaga errores apropiadamente
- Optimización de Memoria
- Reutiliza slices y mapas cuando sea posible
- Libera referencias a objetos grandes
- Usa make con capacidad inicial apropiada
- Concurrencia
- Cierra canales desde el emisor
- Usa canales con buffer cuando sea apropiado
- Considera el uso de select para operaciones timeout