Lekcje modułu (3/5)
Przełącznik typów (type switch)
Przełącznik typu rozróżnia wiele możliwych typów
wartość interfejsu. Jest to uogólnienie comma ok, jeśli takowe istnieją
więcej niż jeden przypadek.
Składnia
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)to specjalna składnia, obowiązująca TYLKO wewnątrzswitch.v := ...wiąże wartość z typem bieżącego przypadku: wewnątrzcase int,vma typint.defaultprzechwytuje wszystkie inne typy; tamvma typ oryginalnego interfejsu.case nildopasowuje interfejs do typu dynamicznego zerowego.
Sprawa „Bezimienna”.
Jeśli nie potrzebujesz wpisanej wartości, możesz pominąć v:
switch i.(type) {
case int:
// you know it's an int, but you don't have a variable of that type
case string:
// ...
}Formularz używany, gdy trzeba po prostu rozróżnić typ, a nie działać na wartość.
Wiele typów w tym samym przypadku
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)
}Typowy przypadek użycia: drukowanie w formacie
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)
}
}Sam fmt.Println wykorzystuje wewnętrznie przełącznik typu do obsługi
standardowe formaty.
Przełącznik typu a odbicie
Dla kilku znanych typów → przełącznik typu (szybki, czytelny).
Do dynamicznej kontroli nieznanych typów → pakiet reflect (więcej
potężny, ale wolniejszy i bardziej gadatliwy).
Spróbuj
Zaimplementuj opis(i interfejs{}) ciąg znaków, który zwraca „int”, „string” lub „altro” w zależności od typu dynamicznego.
Pokaż wskazówkę
Składnia: `switch i.(type) { case T: ... default: ... }`.
Rozwiązanie dostępne po 3 próbach
Napisz printVal(i interfejs{}), który używa v := i.(type) i wyświetla %d dla int, %s dla string.
Pokaż wskazówkę
Wewnątrz `case int` v ma typ int (możesz przekazać go do Printf).
Rozwiązanie dostępne po 3 próbach
Która składnia uruchamia zmianę typu?
switch ??? {
case int: ...
}Podsumowanie
switch v := i.(type) { case T: ... }: rozróżnia typ dynamiczny.- Wewnątrz obudowy pojedynczego typu,
vzawiera typ obudowy. case T1, T2:vzachowuje typ oryginalnego interfejsu.defaultdla nierozwiązanych spraw;case nildla interfejsu zerowego.- Brak kodu
fallthroughw przełącznikach typu. - 1 typ → asercja typu; Ponad 2 typy → przełącznik typu.