Concatenación de slices en Go: de principiante a profesional en 2025
Los slices en Go son arreglos dinámicos que son el corazón de la mayoría de las aplicaciones Go. Tarde o temprano, todo desarrollador se enfrenta a la tarea: «¿Cómo combinar dos slices en uno?». Parece una operación trivial, pero, como muchas cosas en Go, tiene sus trampas y matices de rendimiento.
En Stack Overflow, esta pregunta ha acumulado miles de visitas, y no es para menos: una concatenación no óptima puede provocar asignaciones de memoria innecesarias y reducir la velocidad de la aplicación. En este artículo, analizaremos todas las formas legales de unir dos slices, desde el clásico append hasta las novedades de la biblioteca estándar de 2025, y descubriremos qué método elegir según la situación.
¿Por qué no funciona la simple suma?
A diferencia de Python (list1 + list2) o JavaScript (arr1.concat(arr2)), Go no admite el operador + para slices. Esto se hizo a propósito: Go es un lenguaje que exige claridad. Cada operación con slices debe ser transparente, especialmente en lo que respecta a la gestión de la memoria.
Vayamos directo al grano. Esta es la forma más simple y común:
package main
import "fmt"
func main() { slice1 := []int{1, 2, 3} slice2 := []int{4, 5, 6}
// Método #1: append con desempaquetado result := append(slice1, slice2...) fmt.Println(result) // [1 2 3 4 5 6]}Este código funciona, pero tiene un matiz. Si slice1 tiene suficiente capacidad (cap), entonces append lo modificará a él mismo, en lugar de crear un nuevo slice. Esto puede provocar efectos secundarios inesperados si no esperaba la mutación del slice original.
Concatenación segura mediante make + copy
Si necesita una independencia garantizada del resultado respecto a los slices originales, use la combinación de make y copy. Este es el «estándar de oro» para crear un nuevo slice sin riesgo de modificar el original.
func concatSlices[T any](a, b []T) []T { result := make([]T, len(a)+len(b)) copy(result, a) copy(result[len(a):], b) return result}
// Uso:combined := concatSlices(slice1, slice2)¿Por qué es bueno esto?
- Predecibilidad: Siempre crea un nuevo slice. Los datos originales permanecen intactos.
- Control: Asigna memoria explícitamente una vez, en lugar de depender de la lógica interna de
append. - Genéricos (Go 1.18+): La función funciona con cualquier tipo de dato.
Enfoque moderno: slices.Concat (Go 1.22+)
A partir de la versión Go 1.22 (que para 2025 ya es un estándar desde hace tiempo), en el paquete golang.org/x/exp/slices apareció la función Concat. En Go 1.22 se trasladó a la biblioteca estándar.
Esta es la forma oficial y recomendada de concatenación, que combina la seguridad de copy con la concisión de append.
import "slices"
func main() { a := []string{"Go", "Python", "Rust"} b := []string{"JavaScript", "TypeScript"}
combined := slices.Concat(a, b) // combined = ["Go", "Python", "Rust", "JavaScript", "TypeScript"]}Ventajas de slices.Concat:
- Legibilidad: El nombre habla por sí solo. El código se vuelve declarativo.
- Optimización: Internamente utiliza una asignación eficiente y
copy. - Flexibilidad: Se puede pasar cualquier cantidad de slices:
slices.Concat(s1, s2, s3, s4).
Si escribe código en Go 1.22+ (y en 2025 esto es la corriente principal), use slices.Concat sin dudarlo. Es la mejor opción para el 90% de las tareas.
¿Cuándo todavía se necesita append?
Clásic