Introducción: ¿por qué la pregunta "How to assign string to bytes array" es tan popular?
\n\nSi alguna vez has escrito en Go (Golang) y te has enfrentado a la necesidad de convertir una cadena normal en un array de bytes ([]byte), no estás solo. La pregunta "How to assign string to bytes array" en Stack Overflow acumula decenas de miles de visitas. Parecería sencillo, ¿verdad? Solo tomar y asignar. Pero Go es un lenguaje de tipado estricto, y no se puede simplemente tomar y asignar una cadena a un slice de bytes. Necesitas conocer las técnicas correctas.
En este artículo, analizaremos la conversión de string a bytes array en Go. Te mostraré tres enfoques principales: desde el más simple hasta el súper rápido pero peligroso. Aprenderás qué método elegir según la tarea y dejarás de confundirte con estas conversiones para siempre.
\n\n¡Allá vamos!
\n\nUn poco de teoría: ¿por qué una cadena no es un array de bytes?
\n\nAntes de lanzarnos al código, entendamos por qué Go distingue entre estos dos tipos. Este conocimiento te salvará de una docena de errores.
\n\n- \n
- string en Go es una secuencia de bytes inmutable (immutable). No puedes cambiar un carácter de la cadena por índice. La cadena siempre se almacena como un bloque de memoria de solo lectura. \n
- []byte es un slice de bytes mutable (mutable). Puedes cambiar su contenido, agregar nuevos elementos, etc. \n
Es precisamente debido a esta diferencia de "inmutabilidad" que Go requiere una conversión explícita. Si el compilador permitiera simplemente asignar una cadena a un array de bytes, podrías modificar accidentalmente los datos "protegidos" de la cadena. Por lo tanto, assign string to bytes array siempre requiere una acción consciente de tu parte.
\n\nEnfoque n.º 1: Conversión explícita de tipo (El más simple)
\n\nEsta es la primera forma que se le ocurre a cualquier principiante. ¡Y funciona!
\n\npackage main\n\nimport "fmt"\n\nfunc main() {\n myString := "¡Hola, Go!"\n myBytes := []byte(myString)\n\n fmt.Println(myBytes) // [208 159 209 128 ...] — bytes en UTF-8\n fmt.Println(string(myBytes)) // Lo devolvemos: "¡Hola, Go!"\n}\n\n\nVentajas:
\n- \n
- Máxima simplicidad y legibilidad. \n
- Forma estándar, comprensible para cualquier desarrollador de Go. \n
Desventajas:
\n- \n
- Crea una nueva copia de los datos en memoria. Si la cadena es muy grande (por ejemplo, 10 MB), puede ser costoso en memoria y tiempo. \n
- No es adecuado para sistemas de alta carga donde cada nanosegundo importa. \n
Cuándo usarlo: En el 90% de los casos. Para aplicaciones normales, servicios web y scripts, esto es más que suficiente. No optimices donde no sea necesario.
\n\nEnfoque n.º 2: Uso de copy() (Controlado)
\n\nA veces ya tienes un array de bytes preasignado y quieres llenarlo con datos de una cadena. Aquí es donde la función copy viene al rescate.
package main\n\nimport "fmt"\n\nfunc main() {\n myString := "Go es increíble"\n \n // Creamos un slice de bytes de la longitud necesaria\n myBytes := make([]byte, len(myString))\n \n // Copiamos los datos de la cadena al slice\n n := copy(myBytes, myString)\n \n fmt.Printf("Bytes copiados: %d\\n", n) // 15\n fmt.Println(string(myBytes)) // "Go es increíble"\n}\n\n\nTen en cuenta: copy copia solo la cantidad de bytes que caben en el slice de destino. Si el slice de destino es más corto que la cadena, solo se copiará su longitud. Esto es más seguro que la conversión explícita si no estás seguro del tamaño.
Ventajas:
\n- \n
- Control total sobre el proceso de copia. \n
- Seguridad: no te saldrás de los límites del array. \n
- Se puede usar para copia parcial (subcadena). \n
Desventajas:
\n- \n
- Requiere asignación previa de memoria (
make). \n - De todas formas se crea una copia de los datos.