Sobes.tech
Middle

Come verificare il tipo di una variabile in Go in fase di runtime?

sobes.tech AI

Risposta dell'AI

In Go, il tipo di una variabile in fase di esecuzione può essere verificato in diversi modi:

  1. Utilizzando l'asserzione di tipo: Adatto per verificare un tipo specifico in una variabile di interfaccia.

    package main
    
    import "fmt"
    
    func main() {
        var i interface{} = "ciao"
    
        s, ok := i.(string) // Tentativo di convertire i in tipo string
        if ok {
            fmt.Printf("La variabile i ha tipo string: %s\n", s)
        } else {
            fmt.Println("La variabile i non ha tipo string")
        }
    }
    
  2. Utilizzando lo switch di tipo: Adatto per verificare più tipi possibili in una variabile di interfaccia.

    package main
    
    import "fmt"
    
    func main() {
        var t interface{}
    
        switch tt := t.(type) { // tt avrà un tipo concreto tra i casi
        case int:
            fmt.Printf("La variabile ha tipo int: %d\n", tt)
        case string:
            fmt.Printf("La variabile ha tipo string: %s\n", tt)
        case bool:
            fmt.Printf("La variabile ha tipo bool: %t\n", tt)
        case nil:
            fmt.Println("La variabile ha valore nil")
        default:
            fmt.Printf("Tipo sconosciuto: %T\n", tt) // tt avrà tipo interface{}
        }
    
        t = 123
        switch tt := t.(type) {
        case int:
            fmt.Printf("La variabile ha tipo int: %d\n", tt)
        case string:
            fmt.Printf("La variabile ha tipo string: %s\n", tt)
        case bool:
            fmt.Printf("La variabile ha tipo bool: %t\n", tt)
        case nil:
            fmt.Println("La variabile ha valore nil")
        default:
            fmt.Printf("Tipo sconosciuto: %T\n", tt)
        }
    }
    
  3. Utilizzando il pacchetto reflect: Permette di ottenere informazioni sul tipo e sul valore della variabile in fase di esecuzione. Viene usato quando i tipi sono sconosciuti durante la compilazione o per verifiche più complesse.

    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    func main() {
        var x float64 = 3.4
        v := reflect.ValueOf(x) // Otteniamo il valore di riflessione
    
        fmt.Println("Tipo:", v.Type())                 // Mostra "Tipo: float64"
        fmt.Println("Categoria:", v.Kind())             // Mostra "Categoria: float64"
    
        y := "ciao"
        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"
    }
    

Il pacchetto reflect è più potente, ma anche più complesso da usare. L'asserzione di tipo e lo switch di tipo sono preferiti per verifiche di tipi semplici in variabili di interfaccia, poiché sono più sicuri e orientati al tipo.