Salt la conținutul principal
Modulul 6 · Lecția 3 din 528/50 în curs~10 min
Lecții din modul (3/5)

Comutator de tip

Un comutator de tip discriminează între mai multe tipuri posibile de an valoarea interfeței. Este generalizarea comma ok atunci când există mai mult de un caz.

Sintaxă

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) este o sintaxă specială, valabilă NUMAI în interiorul switch.
  • v := ... leagă valoarea cu tipul cazului curent: în interiorul case int, v are tipul int.
  • default prinde toate celelalte tipuri; acolo v are tipul interfeței originale.
  • case nil potrivește interfața cu un tip dinamic zero.

Caz „fără nume”.

Dacă nu aveți nevoie de valoarea introdusă, puteți omite v:

Go
switch i.(type) {
case int:
    // you know it's an int, but you don't have a variable of that type
case string:
    // ...
}

O formă folosită atunci când trebuie doar să discriminați tipul, nu să operați asupra valorii.

Mai multe tipuri în același caz

Go
switch v := i.(type) {
case int, int64:
    // here v is still interface{}: the "common" type is just the interface
    fmt.Println("numero intero:", v)
case string:
    // here v is string
    fmt.Println("stringa:", v)
}

Caz de utilizare tipic: imprimare formatată

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 în sine folosește un comutator de tip intern pentru a gestiona formate standard.

Tip comutator vs reflexie

Pentru câteva tipuri cunoscute → tip comutator (rapid, lizibil). Pentru inspecția dinamică a tipurilor necunoscute → pachetul reflect (mai multe puternic, dar mai lent și mai pronunțat).

Încearcă

Exercițiu#go.m6.l3.e1
Încercări: 0Se încarcă…

Implementați șirul describe(i interface{}) care returnează „int”, „string” sau „altro”, în funcție de tipul dinamic.

Se încarcă editorul...
Afișează indiciu

Sintaxă: `switch i.(type) { case T: ... implicit: ... }`.

Soluție disponibilă după 3 încercări

Exercițiu#go.m6.l3.e2
Încercări: 0Se încarcă…

Scrieți printVal(i interfață{}) care folosește v := i.(type) și imprimă cu %d pentru int, %s pentru șir.

Se încarcă editorul...
Afișează indiciu

În interiorul `case int`, v are tipul int (puteți trece la Printf).

Soluție disponibilă după 3 încercări

Quiz#go.m6.l3.e3
Gata

Care sintaxă începe o comutare de tip?

Go
switch ??? {
  case int: ...
}
Opțiuni de răspuns

Recapitulare

  • switch v := i.(type) { case T: ... }: discriminează tipul dinamic.
  • În interiorul unei carcase cu un singur tip, v are tipul carcasei.
  • case T1, T2: v păstrează tipul interfeței inițiale.
  • default pentru cazurile netratate; case nil pentru interfața zero.
  • Nu există fallthrough în comutatoarele de tip.
  • 1 tip → tip aserțiune; 2+ tipuri → comutator de tip.