Slice vacío en Go: inicialización correcta con ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Slice vacío en Go: cómo no equivocarse desde el principio

\n\n

Todo desarrollador de Go, tarde o temprano, se enfrenta a la pregunta: "¿cómo inicializar correctamente un slice vacío?". Parece una tarea simple, pero no todo es tan claro. En el FAQ oficial de Go y en Stack Overflow, este tema tiene cientos de comentarios y miles de votos. ¿Por qué?

\n\n

Porque en Go hay dos formas fundamentalmente diferentes de crear un slice vacío, y la elección entre ellas afecta el rendimiento, la legibilidad del código e incluso el comportamiento durante la serialización. Si programas en Go y quieres escribir código limpio y eficiente sin sorpresas, este artículo es para ti.

\n\n

Analizaremos:

\n
    \n
  • En qué se diferencia var s []int de s := make([]int, 0)
  • \n
  • Cuándo usar un nil-slice y cuándo un slice vacío
  • \n
  • Cómo afecta esto a JSON, la memoria y el rendimiento
  • \n
  • Qué dicen los gurús de Go y los autores de la biblioteca estándar
  • \n
\n\n

Dos hermanos gemelos: nil slice vs empty slice

\n\n

En Go, un slice es una estructura de tres campos: puntero a un array, longitud y capacidad. Cuando hablamos de un slice vacío, nos referimos a un slice con longitud 0. Pero la forma en que lo creamos sí importa.

\n\n

Forma 1: Declaración con var (nil slice)

\n\n
var s []int  // s == nil, len(s) == 0, cap(s) == 0
\n\n

Este es un nil-slice. No apunta a ningún array en memoria. Sin embargo, puedes llamar a append sin problemas: Go asignará memoria automáticamente.

\n\n

Forma 2: Inicialización con make (empty slice)

\n\n
s := make([]int, 0)  // s != nil, len(s) == 0, cap(s) == 0
\n\n

Este es un slice vacío. Ya apunta a un array cero (un zerobase especial en el runtime de Go).

\n\n

A primera vista, la diferencia es imperceptible. Pero profundicemos.

\n\n

Salida en consola y JSON — la primera trampa

\n\n

Prueba ejecutar este código:

\n\n
package main\n\nimport (\n    "encoding/json"\n    "fmt"\n)\n\nfunc main() {\n    var nilSlice []int\n    emptySlice := make([]int, 0)\n\n    fmt.Printf("nilSlice: %v, is nil: %v\\n", nilSlice, nilSlice == nil)\n    fmt.Printf("emptySlice: %v, is nil: %v\\n", emptySlice, emptySlice == nil)\n\n    // Serialización JSON\n    nilJSON, _ := json.Marshal(nilSlice)\n    emptyJSON, _ := json.Marshal(emptySlice)\n\n    fmt.Printf("nilSlice JSON: %s\\n", nilJSON)\n    fmt.Printf("emptySlice JSON: %s\\n", emptyJSON)\n}
\n\n

El resultado te sorprenderá:

\n\n
nilSlice: [], is nil: true\nemptySlice: [], is nil: false\nnilSlice JSON: null\nemptySlice JSON: []
\n\n

¡Ahí está la gran sorpresa! La serialización JSON se comporta de manera diferente. Si tu API espera [] en la respuesta y pasas un nil-slice, el cliente recibirá null. Y esto rompe los contratos.

\n\n

Muchos clientes REST (especialmente en JavaScript) verifican estrictamente: si se espera un array en la respuesta y llega null, puede producirse un error o romperse la lógica en el frontend.

\n\n

Rendimiento: ¿hay alguna diferencia?

\n\n

La respuesta corta es: sí, pero en el 99% de los casos es insignificante.

\n\n

Cuando usas make([]int, 0), Go asigna inmediatamente memoria para la estructura del slice (24 bytes en sistemas de 64 bits) y lo vincula con zerobase. Al usar var, la asignación ocurre solo en el primer append.

\n\n

Si creas un slice que probablemente permanecerá vacío, el nil-slice ahorra una asignación de memoria. Si sabes con certeza que agregarás elementos, make especificando la capacidad dará un mejor rendimiento:

\n\n
// Si conoces el tamaño aproximado, especifica la capacidad\ns := make([]int, 0, 100)  // capacidad 100, longitud 0\nfor i := 0; i < 100; i++ {\n    s = append(s, i)  // ¡sin reasignaciones!\n}
\n\n

Pero para la mayoría de las aplicaciones prácticas, la diferencia es

Blogs

Book Recommendations