Librería cast para Go: Guía completa de conversión de tipos
En Go, el tipado estático y estricto es tanto una fortaleza como un desafío. Por un lado, el compilador detecta muchos errores en tiempo de compilación; por otro, el desarrollador debe escribir código verboso para convertir tipos, especialmente al trabajar con datos de fuentes externas (JSON, YAML, bases de datos, peticiones HTTP). La librería cast de Spf13 (autor de Cobra y Viper) resuelve este problema de forma elegante y concisa.
cast proporciona un conjunto de funciones para convertir interfaces (interface{}) a tipos concretos de Go de manera segura y cómoda. En lugar de escribir estructuras complejas con aserciones de tipo y comprobaciones de errores, llamas a una sola función que devuelve un valor por defecto o un error si la conversión no es posible. Esto es especialmente útil al trabajar con configuraciones, analizar respuestas de API y en cualquier escenario donde el tipo de dato solo se conoce en tiempo de ejecución.
La librería no usa reflexión en cada llamada (aunque algunas funciones dependen de ella para conversiones complejas) y está diseñada para ser lo más eficiente posible en los casos típicos. Forma parte del ecosistema de Viper, pero puede usarse como utilidad independiente. Si programas en Go y necesitas convertir cadenas a números, interfaces a slices o mapas a estructuras, cast será tu herramienta indispensable.
Instalación
La instalación de la librería se realiza con la herramienta estándar go get. Ejecuta el siguiente comando en la terminal dentro de tu módulo Go:
go get github.com/spf13/cast
Después de ejecutar el comando, la librería se añadirá al archivo go.mod y estará lista para usar. Asegúrate de tener instalado Go versión 1.16 o superior (se recomienda 1.18+ para soporte de genéricos, aunque cast no los utiliza).
Inicio rápido
Veamos un ejemplo mínimo funcional que demuestra las capacidades básicas de la librería: convertir una cadena a un número entero y una interfaz a una cadena.
package main
import (
"fmt"
"github.com/spf13/cast"
)
func main() {
// Convertimos una cadena a int
num, err := cast.ToIntE("42")
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Número: %d (tipo: %T)\n", num, num)
// Convertimos interface{} a cadena
var val interface{} = "hola mundo"
str := cast.ToString(val)
fmt.Printf("Cadena: %s (tipo: %T)\n", str, str)
// Convertimos con valor por defecto (sin error)
safeNum := cast.ToInt("no es número") // devuelve 0
fmt.Printf("Número seguro: %d\n", safeNum)
}
Como ves, el código es limpio y claro. Las funciones con el sufijo E devuelven un error; las que no lo tienen, devuelven el valor cero en caso de fallo.
Métodos y funciones principales
La librería cast ofrece una amplia gama de funciones para trabajar con diferentes tipos de datos. A continuación se presentan 8+ funciones clave con descripción y ejemplos.
1. ToString
Firma: func ToString(i interface{}) string
Qué hace: Convierte el valor proporcionado en una cadena. Soporta tipos numéricos, valores booleanos, slices de bytes, cadenas e interfaces.
package main
import (
"fmt"
"github.com/spf13/cast"
)
func main() {
fmt.Println(cast.ToString(123)) // "123"
fmt.Println(cast.ToString(45.67)) // "45.67"
fmt.Println(cast.ToString(true)) // "true"
fmt.Println(cast.ToString([]byte("go"))) // "go"
fmt.Println(cast.ToString(nil)) // ""
}
2. ToInt
Firma: func ToInt(i interface{}) int
Qué hace: Convierte el valor a int. Funciona con cadenas, números y otros tipos compatibles.
package main
import (
"fmt"
"github.com/spf13/cast"
)
func main() {
fmt.Println(cast.ToInt("42")) // 42
fmt.Println(cast.ToInt(3.14)) // 3
fmt.Println(cast.ToInt(true)) // 1
fmt.Println(cast.ToInt(false)) // 0
fmt.Println(cast.ToInt("error")) // 0 (valor por defecto)
}
3. ToInt64
Firma: func ToInt64(i interface{}) int64
Qué hace: Similar a ToInt, pero devuelve un valor de tipo int64. Ideal para trabajar con identificadores grandes o timestamps.
package main
import (
"fmt"
"github.com/spf13/cast"
)
func main() {
var id interface{} = "9876543210"
intID := cast.ToInt64(id)
fmt.Printf("ID: %d (tipo: %T)\n", intID, intID) // ID: 9876543210 (tipo: int64)
}
4. ToFloat64
Firma: func ToFloat64(i interface{}) float64
Qué hace: Convierte el valor a float64. Maneja cadenas con decimales, números enteros y booleanos.
package main
import (
"fmt"
"github.com/spf13/cast"
)
func main() {
fmt.Println(cast.ToFloat64("3.1416")) // 3.1416
fmt.Println(cast.ToFloat64(42)) // 42.0
fmt.Println(cast.ToFloat64(true)) // 1.0
}
5. ToBool
Firma: func ToBool(i interface{}) bool
Qué hace: Convierte el valor a booleano. Reconoce cadenas como "true", "false", "1", "0", "yes", "no", etc.
package main
import (
"fmt"
"github.com/spf13/cast"
)
func main() {
fmt.Println(cast.ToBool("true")) // true
fmt.Println(cast.ToBool("1")) // true
fmt.Println(cast.ToBool("yes")) // true
fmt.Println(cast.ToBool("false")) // false
fmt.Println(cast.ToBool(0)) // false
}
6. ToStringSlice
Firma: func ToStringSlice(i interface{}) []string
Qué hace: Convierte un slice de interfaces o una cadena separada por comas en un slice de cadenas.
package main
import (
"fmt"
"github.com/spf13/cast"
)
func main() {
slice := cast.ToStringSlice([]interface{}{"a", "b", "c"})
fmt.Println(slice) // [a b c]
str := cast.ToStringSlice("uno,dos,tres")
fmt.Println(str) // [uno dos tres]
}
7. ToIntSlice
Firma: func ToIntSlice(i interface{}) []int
Qué hace: Convierte un slice de interfaces o una cadena de números separados por comas en un slice de enteros.
package main
import (
"fmt"
"github.com/spf13/cast"
)
func main() {
nums := cast.ToIntSlice([]interface{}{"1", 2, 3.0})
fmt.Println(nums) // [1 2 3]
}
8. ToStringMap
Firma: func ToStringMap(i interface{}) map[string]interface{}
Qué hace: Convierte un mapa genérico (map[interface{}]interface{} u otros) en un mapa con claves de tipo cadena. Muy útil al trabajar con datos JSON o YAML.
package main
import (
"fmt"
"github.com/spf13/cast"
)
func main() {
raw := map[interface{}]interface{}{
"nombre": "Ana",
"edad": 30,
}
result := cast.ToStringMap(raw)
fmt.Println(result["nombre"]) // Ana
fmt.Println(result["edad"]) // 30
}
9. ToTime
Firma: func ToTime(i interface{}) time.Time
Qué hace: Convierte una cadena o un número (timestamp Unix) en un objeto time.Time. Soporta múltiples formatos de fecha.
package main
import (
"fmt"
"github.com/spf13/cast"
)
func main() {
t := cast.ToTime("2024-12-25T10:00:00Z")
fmt.Println(t) // 2024-12-25 10:00:00 +0000 UTC
ts := cast.ToTime(int64(1703491200))
fmt.Println(ts) // 2024-12-25 00:00:00 +0000 UTC
}
10. ToDuration
Firma: func ToDuration(i interface{}) time.Duration
Qué hace: Convierte una cadena (ej. "5s", "10m", "2h") o un número (en nanosegundos) en un objeto time.Duration.
package main
import (
"fmt"
"github.com/spf13/cast"
)
func main() {
d := cast.ToDuration("5s")
fmt.Println(d) // 5s
d2 := cast.ToDuration(3000000000) // 3 segundos en nanosegundos
fmt.Println(d2) // 3s
}
Conclusión
La librería cast es una herramienta esencial para cualquier desarrollador Go que trabaje con datos dinámicos o conversiones de tipos frecuentes. Su API simple y consistente reduce significativamente el código boilerplate y minimiza los errores. Ya sea que estés construyendo una CLI con Cobra, gestionando configuraciones con Viper, o simplemente necesites convertir tipos de forma segura, cast te ahorrará tiempo y dolores de cabeza.
Para más información, consulta la documentación oficial en GitHub.
También en la biblioteca
Planificador de tareas en C# (.NET): Quartz.NET, Hangfire, Coravel
Bouncy Castle Java: guía completa de criptografía con ejemplos
Configuración de aplicaciones Node.js: mejores herramientas y enfoques
RapidJSON para C++: guía completa con ejemplos prácticos
Trabajo con S3 y almacenamiento en la nube en JavaScript (Node.js) — biblioteca @aws-sdk/client-s3