Cast para Go: guía completa con ejemplos prácticos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

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.

Recommendations