Cómo unir un slice de cadenas en Go: principales errores y cómo evitarlos
\n\n¿Alguna vez has escrito en Go y de repente te has dado cuenta: «Necesito unir todas estas cadenas en una, pero ¿cómo hacerlo correctamente?» Esta pregunta es una de las más populares en Stack Overflow (decenas de miles de visitas). Parece sencillo, ¿verdad? Pero los principiantes (y no solo ellos) logran pisar los mismos rastrillos: ralentizan el código, consumen mucha memoria u obtienen errores inesperados.
\n\nEn este artículo, analizaremos tres errores típicos al unir un slice de cadenas en Go y mostraremos cómo evitarlos. Aprenderás a elegir la herramienta adecuada para cada tarea, desde una simple unión hasta aplicaciones de alta carga. ¡Allá vamos!
\n\n¿Por qué es tan importante este tema?
\n\nTrabajar con cadenas es la base de cualquier lenguaje de programación. En Go, las cadenas son inmutables (immutable). Cuando «unes» dos cadenas con el operador +, en realidad se crea una nueva cadena y las antiguas se copian. En un bucle, esto se convierte en una complejidad cuadrática O(n²). Y si hay muchas cadenas (cientos de miles), el programa puede ralentizarse o incluso fallar con out of memory.
Además, Go es un lenguaje donde el rendimiento es importante. Por eso, la biblioteca estándar ofrece soluciones elegantes. Veamos qué errores se cometen con más frecuencia.
\n\nError n.º 1: Concatenación en bucle con +=
\n\nCómo se ve en la práctica
\n\nSupongamos que tienes un slice de cadenas:
\n\nwords := []string{"Go", "is", "awesome", "but", "only", "if", "you", "use", "the", "right", "tools"}\n\nLa forma más intuitiva es recorrer el slice y agregar cada palabra:
\n\nresult := ""\nfor _, w := range words {\n result += w + " "\n}\nfmt.Println(result) // "Go is awesome but only if you use the right tools "\n\nParece lógico, ¿verdad? Pero esto es una bomba de tiempo.
\n\n¿Por qué es malo?
\n\n- \n
- Copia de memoria. Cada iteración crea una nueva cadena, copiando todos los datos anteriores. Para 1000 cadenas de 10 caracteres, eso son ~500 000 copias innecesarias. \n
- Gran cantidad de asignaciones. En lugar de una cadena, creas n cadenas, cada una de las cuales luego es eliminada por el recolector de basura. \n
- Código poco legible. Es fácil olvidar los espacios o separadores. \n
¿Cuándo es aceptable? Solo si son 2 o 3 cadenas y estás escribiendo un script de un solo uso. Para producción, nunca.
\n\nError n.º 2: Usar strings.Join con un separador vacío (y no entender su potencia)
\n\nEl héroe correcto
\n\nLa biblioteca estándar de Go nos ofrece strings.Join. Es la solución ideal para el 90% de los casos:
import "strings"\n\nwords := []string{"Go", "is", "awesome"}\nresult := strings.Join(words, " ")\nfmt.Println(result) // "Go is awesome"\n\nEl código se lee como un libro: «une words con un espacio». Y funciona rápido: strings.Join calcula previamente la longitud final de la cadena y asigna memoria exactamente una vez.
¿Cómo se equivocan?
\n\n- \n
- Olvidan el separador.
strings.Join(words, "")une todo sin separación. A veces es necesario, pero a menudo es un error. \n - Usan
strings.Joinpara una concatenación única. No hagas esto:strings.Join([]string{a, b}, ""). Simplemente escribea + b. \n - No manejan un slice vacío.
strings.Join([]string{}, ",")devuelve una cadena vacía. Esto es normal, pero los principiantes esperan un error. \n
// Ejemplo donde Join no es adecuado\ndata := []string{}\nresult := strings.Join(data, ",") // "" — vacío, pero a veces se necesita ","\n// Entonces habría que hacer una comprobación:\nif len(data) > 0 {\n result = "," + strings.Join(data, ",")\n}\n\nConclusión: strings.Join es tu amigo. Úsalo siempr