{}const=>[]async()letfn</>var
Desarrollo

Cortes bajo el microscopio: capacidad, copia, crecimiento y trampas en Go

Analizamos las particiones en Go bajo el capó: cómo funcionan, por qué la capacidad decide, por qué son peligrosos los arrays comunes y cómo evitar errores ocultos.

К

Kodik

Autor

3 min de lectura

Las rebanadas en Go son una de las herramientas más poderosas pero también más traicioneras del lenguaje. A primera vista, parecen ser simplemente «matrices dinámicas», pero bajo el capó tienen suficientes matices para que una línea de código se convierta en un error, cuya depuración llevará varias horas. Veamos cómo funcionan realmente.

En qué consiste el corte

Una rebanada en Go no es una matriz. Es un «envoltorio fino» que almacena:

  • Puntero a matriz — el lugar real de almacenamiento de datos.

  • Longitud (len) — cuántos elementos están disponibles en este momento.

  • Capacidad (cap) — cuántos elementos se pueden acomodar sin reasignar la memoria.

 s := []int{1, 2, 3, 4}
 fmt.Println(len(s)) // 4
 fmt.Println(cap(s)) // 4
🔥 100.000+ estudiantes ya están con nosotros

¿Cansado de leer teoría?
¡Hora de programar!

Kodik — una app donde aprendes a programar con práctica. Mentor IA, lecciones interactivas, proyectos reales.

🤖 IA 24/7
🎓 Certificados
💰 Gratis
🚀 Empezar
Se unieron hoy

Capacity y su papel

La capacidad es un margen. Cuando hacemos append, Go comprueba:

  • Si hay suficiente capacidad, los nuevos elementos simplemente se escriben en la misma matriz.

  • Si la capacidad se ha agotado, Go crea nueva matriz de mayor tamaño y copia los datos antiguos allí.

 s := make([]int, 2, 4) // len=2, cap=4
 s = append(s, 10, 20)  // todavía hay espacio
 fmt.Println(cap(s))    // 4
 s = append(s, 30)      // cap se ha agotado → nueva matriz
 fmt.Println(cap(s))    // 8

Copy y sus dificultades

La función copy hace una copia superficial:

 a := []int{1, 2, 3}
 b := make([]int, len(a))
 copy(b, a)
 b[0] = 99
 fmt.Println(a) // [1 2 3]
 fmt.Println(b) // [99 2 3]

Pero si simplemente asignas:

 a := []int{1, 2, 3}
 b := a
 b[0] = 99
 fmt.Println(a) // [99 2 3] ❗

Aquí a y b apuntan a la misma matriz, un error común de los principiantes.

Grow: cómo crecen los segmentos

Go no garantiza un algoritmo de crecimiento preciso, pero generalmente funciona de la siguiente manera:

  • Si la capacidad es pequeña, se duplica.

  • Si la capacidad ya es grande, aumenta aproximadamente en un 25 %.

👉 Por lo tanto, cuando se trabaja con grandes cantidades de datos, es mejor asignar make([]T, 0, N) con antelación y con el margen necesario.

Pitfalls: dónde se equivocan los desarrolladores con más frecuencia

  1. Matriz subyacente común

     a := []int{1, 2, 3, 4, 5}
     b := a[:3]
     c := a[2:]
     c[0] = 99
     fmt.Println(b) // [1 2 99] 😱

    b y c utilizan la misma matriz.

  2. El crecimiento rompe la «conexión»

     a := []int{1, 2, 3}
     b := a
     a = append(a, 4) // cap agotado → nueva matriz
     b[0] = 99
     fmt.Println(a) // [1 2 3 4]
     fmt.Println(b) // [99 2 3]

    Después del crecimiento, a ya tiene otra matriz, y la conexión con b se ha perdido.

  3. Cortes de una gran matriz

     big := make([]byte, 1e6)
     small := big[:1]
     // small parece pequeño, pero guarda en la memoria todo el megabyte

    Solución: copy en una nueva sección.

Total

Los datos en Go son una herramienta útil, pero:

  • recuerda la capacidad y el crecimiento,

  • utilice copy si desea datos independientes,

  • tenga cuidado con los «cortes de los cortes».

Comprender la estructura de las secciones bajo el capó te evitará errores inesperados y te ayudará a escribir un código más fiable.

🎯Deja de postergar

¿Te gustó el artículo?
¡Hora de practicar!

En Kodik no solo lees — escribes código de inmediato. Teoría + práctica = habilidades reales.

Práctica instantánea
🧠IA explica código
🏆Certificado

Sin registro • Sin tarjeta