Vai al contenuto
eLearner.app
Modulo 6 · Lezione 3 di 528/50 nel corso~10 min
Lezioni del modulo (3/5)

Type switch

Un type switch discrimina su più tipi possibili di un valore di interfaccia. È la generalizzazione del comma ok quando i casi sono più di uno.

Sintassi

Go
func describe(i interface{}) string {
    switch v := i.(type) {
    case int:
        return fmt.Sprintf("int %d", v)
    case string:
        return fmt.Sprintf("string %q", v)
    case nil:
        return "nil"
    default:
        return fmt.Sprintf("altro tipo: %T", v)
    }
}
  • i.(type) è una sintassi speciale, valida SOLO dentro switch.
  • v := ... lega il valore con il tipo del case corrente: dentro case int, v è di tipo int.
  • default cattura tutti gli altri tipi; lì v ha il tipo dell'interfaccia originale.
  • case nil matcha l'interfaccia con tipo dinamico nil.

Caso "senza nome"

Se non ti serve il valore tipizzato, puoi omettere la v:

Go
switch i.(type) {
case int:
    // sai che è int, ma non hai una variabile di quel tipo
case string:
    // ...
}

Forma usata quando devi solo discriminare il tipo, non operare sul valore.

Più tipi nello stesso case

Go
switch v := i.(type) {
case int, int64:
    // qui v è interface{} ancora: il tipo "comune" è solo l'interfaccia
    fmt.Println("numero intero:", v)
case string:
    // qui v è string
    fmt.Println("stringa:", v)
}

Caso d'uso tipico: stampa formattata

Go
func print(i interface{}) {
    switch v := i.(type) {
    case int:
        fmt.Printf("%d\n", v)
    case string:
        fmt.Printf("%s\n", v)
    case fmt.Stringer:
        fmt.Println(v.String())
    default:
        fmt.Printf("%v\n", v)
    }
}

fmt.Println stesso usa un type switch internamente per gestire i formati standard.

Type switch vs riflessione

Per pochi tipi noti → type switch (veloce, leggibile). Per ispezione dinamica di tipi sconosciuti → pacchetto reflect (più potente ma più lento e più verboso).

Prova tu

Esercizio#go.m6.l3.e1
Tentativi: 0Caricamento…

Implementa describe(i interface{}) string che ritorna 'int', 'string' o 'altro' secondo il tipo dinamico.

Caricamento editor…
Mostra suggerimento

Sintassi: `switch i.(type) { case T: ... default: ... }`.

Soluzione disponibile dopo 3 tentativi

Esercizio#go.m6.l3.e2
Tentativi: 0Caricamento…

Scrivi printVal(i interface{}) che usa v := i.(type) e stampa con %d per int, %s per string.

Caricamento editor…
Mostra suggerimento

Dentro `case int`, v è di tipo int (lo puoi passare a Printf).

Soluzione disponibile dopo 3 tentativi

Quiz#go.m6.l3.e3
Pronto

Quale sintassi avvia un type switch?

Go
switch ??? {
  case int: ...
}
Opzioni di risposta

Recap

  • switch v := i.(type) { case T: ... }: discrimina sul tipo dinamico.
  • Dentro un case a tipo singolo, v è del tipo del case.
  • case T1, T2: v mantiene il tipo dell'interfaccia originale.
  • default per il caso non gestito; case nil per l'interfaccia nil.
  • Niente fallthrough nei type switch.
  • 1 tipo → type assertion; 2+ tipi → type switch.