Ce face type switch
switch v := x.(type) verifică tipul concret al valorii din interfața x și execută ramura potrivită. În fiecare ramură cu un singur tip, v are deja acel tip, deci îl poți folosi direct (v * 2 pentru int, len(v) pentru string).
O ramură poate lista mai multe tipuri (case int, int64:); atunci v rămâne de tipul interfeței. case nil: prinde interfața goală, iar default orice alt tip. Ramurile pot fi și interfețe (case fmt.Stringer:). Cuvântul .(type) se poate folosi doar într-un switch, iar fallthrough nu este permis.
Exemple
Exemplul 1: Descrierea unor valori de tipuri diferite
package main
import "fmt"
func descrie(x any) string {
switch v := x.(type) {
case nil:
return "nimic"
case int:
return fmt.Sprintf("întreg, pătratul este %d", v*v)
case float64:
return fmt.Sprintf("real, jumătatea este %.2f", v/2)
case string:
return fmt.Sprintf("text cu %d octeți", len(v))
case []int:
return fmt.Sprintf("listă cu %d numere", len(v))
case bool, error:
return fmt.Sprintf("bool sau eroare: %v", v)
default:
return fmt.Sprintf("tip necunoscut %T", v)
}
}
func main() {
for _, x := range []any{7, 2.5, "Brașov", []int{1, 2, 3}, true, nil, 'a'} {
fmt.Println(descrie(x))
}
}
Rezultat
întreg, pătratul este 49
real, jumătatea este 1.25
text cu 7 octeți
listă cu 3 numere
bool sau eroare: true
nimic
tip necunoscut int32
Exemplul 2: Ramuri cu interfețe
Ramurile se verifică în ordine; un tip care are String() intră pe ramura fmt.Stringer.
package main
import (
"errors"
"fmt"
)
type Oras struct{ Nume string }
func (o Oras) String() string { return "orașul " + o.Nume }
func afiseaza(x any) {
switch v := x.(type) {
case error:
fmt.Println("eroare:", v.Error())
case fmt.Stringer:
fmt.Println("stringer:", v.String())
default:
fmt.Println("valoare:", v)
}
}
func main() {
afiseaza(Oras{"Sibiu"})
afiseaza(errors.New("fișier lipsă"))
afiseaza(100)
}
Rezultat
stringer: orașul Sibiu
eroare: fișier lipsă
valoare: 100
Greșeli frecvente
x.(type)în afara unuiswitch:invalid syntax tree: use of .(type) outside type switch.- Așteptarea ca
vsă aibă tipul concret într-o ramură cu mai multe tipuri: rămâne interfață. fallthroughîntr-un type switch: nu este permis.
Comenzi înrudite
type assertion: Scoate valoarea concretă dintr-o interfață: x.(T) verifică dacă interfața ține tipul T și îl returnează.switch, case și default: Alege una din mai multe ramuri după valoarea unei expresii sau după prima condiție adevărată.interface și interfețe: Interfața descrie un set de metode; orice tip care le are o implementează automat, fără declarație explicită.any: Alias pentru interface{}: un tip care poate ține orice valoare; folosit și drept constrângere în generics.