Honestamente no sabía muy bien como comenzar este artículo, es un tema bastante sutil y algo abstracto para explicarlo bonito en un artículo. Quiero que abras tu mente y que juntos desempolvemos el libro de ingeniería de software.
Siempre que comienzas un curso de lo que sea, te enseñan que un char es un byte. Personalmente me parecía un poco perdida de tiempo, porque en la vida real, realmente no son demasiado importantes, como mucho los usarás una o dos veces en tu vida. El 99.9999999999% de las veces usarás un string.
Si vienes de lenguajes como C o Java de la vieja escuela, estás acostumbrado a que un char es un byte. Punto. Pero en el mundo moderno, donde usamos emojis para todo y nombres con tildes, esa lógica se rompe más rápido que una promesa de político o de un criptobro.
En Go, existe algo llamado Runa (rune). Al principio parece un nombre místico sacado de El Señor de los Anillos, pero su función es mucho más terrenal y necesaria: es la forma en que Go maneja Unicode.
El engaño de los Strings
En Go, un string es simplemente una secuencia de bytes. Esto es súper eficiente para la memoria, pero tiene una trampa. Mira este ejemplo:
nombre := "José"
fmt.Println(len(nombre))
// Uno esperaría un 4... ¡pero sale 5!
¿Por qué? Porque la é no cabe en un solo byte. En formato UTF-8, esa tilde ocupa 2 bytes. Si intentas recorrer este string con un for tradicional, vas a terminar imprimiendo basura porque estarás cortando la é a la mitad.
Esto es súper contra intuitivo, al principio y puede ser un dolor de cabeza si tu libro de ingeniería de software tiene tela de araña y polvo de Egipto. Es momento de volver a las bases.
¿Qué es exactamente una Runa?
Técnicamente, una rune es solo un alias para int32. Pero su significado real es: “Un punto de código Unicode”.
Mientras que un byte solo puede representar 256 valores, una runa de 32 bits tiene espacio para representar prácticamente cualquier símbolo creado por la humanidad (y los que faltan que nos muestren los aliens cuando nos visiten).
La Runa es la unidad mínima de texto legible. El byte es la unidad mínima de almacenamiento.
¿Para qué sirve en la vida real?
Si eres un desarrollador fullstack como yo, te tocará limpiar datos o validar nombres. Si intentas invertir un string o contar sus letras basándote en bytes, vas a romper el texto.
Imagina que estás regresando el nombre de un cliente para un Banco, para que se imprima en su tarjeta de crédito Black Dark Oro Planito Súper de Luxure que solo permite 50 caracteres. Si usas len(), vas a cortar la tilde de la é y la o de la ó, lo que va a resultar en un nombre que no es el correcto.
Aquí es donde las runas nos salvan la vida:
saludo := "Hola ✅"
// Forma incorrecta (cuenta bytes)
fmt.Println("Bytes:", len(saludo)) // Resultado: 13
// Forma correcta (usando runas)
import "unicode/utf8"
fmt.Println("Caracteres:", utf8.RuneCountInString(saludo)) // Resultado: 7
Incluso cuando haces un range en un string, Go es lo suficientemente inteligente para convertir esos bytes en runas automáticamente:
for i, r := range "José ✅" {
fmt.Printf("Posición %d: %c\n", i, r)
}
// Notarás que se salta el índice 2 porque la 'é' ocupa la posición 1 y 2.
¿Cuándo deberías preocuparte por las Runas?
- Validaciones de longitud: Si tu base de datos aguanta 50 caracteres, usa
RuneCountInString, nolen(). - Procesamiento de texto: Si vas a recortar un nombre o transformar caracteres.
- Soporte Multi-idioma: Para que tu app no explote cuando un usuario de Japón o de Honduras escriba algo que no sea ASCII puro.
Conclusión
Las runas son la forma en que Go nos obliga a ser mejores programadores. Nos sacan de nuestra zona de confort de “un carácter = un byte” y nos preparan para un software que realmente pueda ser usado en todo el mundo.
Dominar las runas es dejar de ver el texto como una simple cadena y empezar a verlo como una colección de símbolos con sentido.
¿Te sirvió? Si te quedó alguna duda sobre cómo convertir un slice de bytes a runas o viceversa, ¡házmelo saber en los comentarios!