El tipo bool en Go es lo que ves: un valor binario que solo puede ser true o false. A diferencia de lenguajes como C o JavaScript, en Go no existe el concepto de “truthy” o “falsy”; esto significa que un entero como 1 no se evalúa como verdadero ni un 0 como falso. Esta restricción es una decisión de diseño para garantizar la seguridad de tipos y evitar errores lógicos accidentales en condiciones complejas. Para usar un valor en un if, este debe ser explícitamente un bool.
Por otro lado, un string no es una lista de caracteres, sino una secuencia inmutable de bytes que representa texto. Internamente, el runtime de Go implementa los strings de forma muy eficiente: no utilizan un terminador nulo (como el \0 de C) para marcar el final, sino que son una estructura pequeña que contiene un puntero al área de memoria donde residen los bytes y su longitud (len). Esto permite que la creación de sub-strings (slicing) sea una operación de tiempo constante $O(1)$, ya que solo se crea una nueva cabecera con un puntero desplazado, sin copiar los datos subyacentes. Sin embargo, como un string es una secuencia de bytes y el estándar de la industria es UTF-8, debes tener cuidado: len(s) te devolverá la cantidad de bytes, no la cantidad de caracteres visuales (conocidos como runes). Si intentas contar caracteres en una cadena que contiene emojis o tildes usando len(), los resultados serán incorrectos.
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
// --- El tipo bool ---
// En Go, la evaluación debe ser explícita.
edad := 25
esMayorDeEdad := edad >= 18 // El resultado es un valor de tipo bool
// Esto es correcto:
if esMayorDeEdad {
fmt.Println("Acceso concedido")
}
// Esto daría un error de compilación: if edad { ... }
// Porque edad es int, no bool.
// --- El tipo string ---
// Un string es una vista inmutable sobre un array de bytes.
mensaje := "Hola, Gopher! 🚀"
// 1. len() devuelve la cantidad de bytes.
// El emoji 🚀 ocupa 4 bytes en UTF-8.
fmt.Printf("Mensaje: %s\n", mensaje)
fmt.Printf("Longitud en bytes (len): %d\n", len(mensaje))
// 2. Para contar caracteres reales (runes), usamos el paquete unicode/utf8.
caracteresReales := utf8.RuneCountInString(mensaje)
fmt.Printf("Cantidad de caracteres (runes): %d\n", caracteresReales)
// 3. Los strings son inmutables.
// No puedes hacer: mensaje[0] = 'h' (esto fallaría al compilar).
// 4. El slicing es muy eficiente porque no copia el contenido,
// solo crea una nueva cabecera con un puntero y longitud distintos.
subMensaje := mensaje[0:4] // "Hola"
fmt.Printf("Sub-string: %s\n", subMensaje)
}
En el ejemplo anterior, observa cómo esMayorDeEdad es el resultado de una comparación, lo que garantiza que el if reciba exactamente lo que espera. Si intentaras pasar edad directamente, el compilador te detendría, obligándote a ser claro en tu intención lógica.
Cuando analizamos el manejo de mensaje, la diferencia entre len(mensaje) y utf8.RuneCountInString(mensaje) es crítica. El primer comando te dice cuántos bytes ocupa el mensaje en memoria; en este caso, incluye los 4 bytes que consume el emoji de la nave espacial. El segundo comando recorre la secuencia de bytes interpretando las reglas de UTF-8 para contar unidades de texto reales. Fíjate también en subMensaje: estamos creando una nueva variable que apunta a una porción del mismo bloque de memoria de mensaje. Esto es extremadamente rápido, pero recuerda que si modificas un slice de un string (aunque el string sea inmutable, el slice de bytes sí lo es en otros contextos), podrías afectar la memoria subyacente.
El error frecuente
Un error clásico cuando vienes de otros lenguajes es asumir que len() te da la longitud de la cadena de texto para fines de lógica de negocio.
s := "Café" fmt.Println(len(s)) // Imprime 5, no 4.
Esto sucede porque la é es un carácter Unicode que, al codificarse en UTF-8, utiliza 2 bytes. Si usas el resultado de len(s) para iterar sobre un string con un bucle for i := 0; i < len(s); i++, terminarás iterando sobre bytes individuales y no sobre caracteres, lo que te dará valores corruptos o inválidos cuando encuentres caracteres multibyte.
N° 20