Sobes.tech
Middle

Como verificar o tipo de uma variável em Go em tempo de execução?

sobes.tech IA

Resposta da IA

Em Go, o tipo de uma variável em tempo de execução pode ser verificado de várias maneiras:

  1. Usando asserção de tipo: Adequado para verificar um tipo específico numa variável de interface.

    package main
    
    import "fmt"
    
    func main() {
        var i interface{} = "olá"
    
        s, ok := i.(string) // Tentativa de converter i para tipo string
        if ok {
            fmt.Printf("A variável i tem tipo string: %s\n", s)
        } else {
            fmt.Println("A variável i não tem tipo string")
        }
    }
    
  2. Usando switch de tipo: Adequado para verificar vários tipos possíveis numa variável de interface.

    package main
    
    import "fmt"
    
    func main() {
        var t interface{}
    
        switch tt := t.(type) { // tt terá um tipo concreto dos casos
        case int:
            fmt.Printf("A variável tem tipo int: %d\n", tt)
        case string:
            fmt.Printf("A variável tem tipo string: %s\n", tt)
        case bool:
            fmt.Printf("A variável tem tipo bool: %t\n", tt)
        case nil:
            fmt.Println("A variável tem valor nil")
        default:
            fmt.Printf("Tipo desconhecido: %T\n", tt) // tt terá tipo interface{}
        }
    
        t = 123
        switch tt := t.(type) {
        case int:
            fmt.Printf("A variável tem tipo int: %d\n", tt)
        case string:
            fmt.Printf("A variável tem tipo string: %s\n", tt)
        case bool:
            fmt.Printf("A variável tem tipo bool: %t\n", tt)
        case nil:
            fmt.Println("A variável tem valor nil")
        default:
            fmt.Printf("Tipo desconhecido: %T\n", tt)
        }
    }
    
  3. Usando o pacote reflect: Permite obter informações sobre o tipo e valor da variável em tempo de execução. Usado quando os tipos são desconhecidos na compilação ou para realizar verificações mais complexas.

    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    func main() {
        var x float64 = 3.4
        v := reflect.ValueOf(x) // Obtemos o valor de reflexão
    
        fmt.Println("Tipo:", v.Type())                 // Mostra "Tipo: float64"
        fmt.Println("Categoria:", v.Kind())             // Mostra "Categoria: float64"
    
        y := "olá"
        vv := reflect.ValueOf(y)
        fmt.Println("Tipo:", vv.Type())               // Mostra "Tipo: string"
        fmt.Println("Categoria:", vv.Kind())           // Mostra "Categoria: string"
    
        z := []int{1, 2, 3}
        vvv := reflect.ValueOf(z)
        fmt.Println("Tipo:", vvv.Type())             // Mostra "Tipo: []int"
        fmt.Println("Categoria:", vvv.Kind())         // Mostra "Categoria: slice"
    }
    

O pacote reflect é mais poderoso, mas também mais complexo de usar. A asserção de tipo e o switch de tipo são preferidos para verificações simples de tipos em variáveis de interface, pois são mais seguros e orientados ao tipo.