Un slice es un array dinámico, la unidad estructural principal al trabajar con arrays en Go. Históricamente, los lenguajes de programación ofrecían arrays fijos o estructuras más pesadas. Go implementó slices como una herramienta conveniente para manejar colecciones de memoria con gestión automática de su tamaño y la capacidad de cambiar la longitud.
El problema radica en la gestión adecuada de la memoria, manejo de casos límite (slices vacíos, nil, llenos) y en entender la diferencia entre la longitud y la capacidad de un slice.
La solución es utilizar correctamente las funciones integradas len(), cap(), y operar con slices de acuerdo con las convenciones de Go.
Ejemplo de código:
var a []int // nil slice, len=0, cap=0 b := make([]int, 0) // slice vacío, len=0, cap=0 c := make([]int, 3, 5) // len=3, cap=5 c = append(c, 4, 5, 6) // cap se incrementará automáticamente
Características clave:
var s []int) no asigna memoria en absoluto, se diferencia de un slice vacío (make([]int, 0)) solo internamente.¿Qué longitud y capacidad tendrá un slice después de append a un nil slice?
El nil slice (var s []int) después de append(s, 1) se convierte en un slice de longitud 1, capacidad 1 — Go maneja la asignación de memoria automáticamente.
var s []int s = append(s, 42) // s ahora es [42], len=1, cap=1
¿Se puede acceder a la capacity de un slice que es nil?
Sí, en el nil slice ambas funciones — len y cap — devuelven 0. No habrá pánico.
var s []int fmt.Println(len(s), cap(s)) // 0 0
¿Qué sucederá si intento asignar a un elemento por índice sin asignar memoria previamente a un slice que es nil?
Pánico index out of range, porque el slice no tiene elementos.
var s []int s[0] = 1 // pánico: error de tiempo de ejecución: índice fuera de rango
El equipo decidió usar únicamente var s []T en el servidor Go, esperando que esto siempre fuera equivalente a make([]T, 0). Como resultado, algunas marshaling de json devolvían null en lugar de [].
Ventajas:
Desventajas:
Uso de make([]T, 0, 100) para preasignación, y luego solo append en el ciclo. Esto minimiza las asignaciones de memoria y a menudo se traduce en un rendimiento mejorado.
Ventajas:
Desventajas: