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ă
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 interiorulswitch.v := ...leagă valoarea cu tipul cazului curent: în interiorulcase int,vare tipulint.defaultprinde toate celelalte tipuri; acolovare tipul interfeței originale.case nilpotrivește interfața cu un tip dinamic zero.
Caz „fără nume”.
Dacă nu aveți nevoie de valoarea introdusă, puteți omite v:
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
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ă
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ă
Implementați șirul describe(i interface{}) care returnează „int”, „string” sau „altro”, în funcție de tipul dinamic.
Afișează indiciu
Sintaxă: `switch i.(type) { case T: ... implicit: ... }`.
Soluție disponibilă după 3 încercări
Scrieți printVal(i interfață{}) care folosește v := i.(type) și imprimă cu %d pentru int, %s pentru șir.
Afișează indiciu
În interiorul `case int`, v are tipul int (puteți trece la Printf).
Soluție disponibilă după 3 încercări
Care sintaxă începe o comutare de tip?
switch ??? {
case int: ...
}Recapitulare
switch v := i.(type) { case T: ... }: discriminează tipul dinamic.- În interiorul unei carcase cu un singur tip,
vare tipul carcasei. case T1, T2:vpăstrează tipul interfeței inițiale.defaultpentru cazurile netratate;case nilpentru interfața zero.- Nu există
fallthroughîn comutatoarele de tip. - 1 tip → tip aserțiune; 2+ tipuri → comutator de tip.