Przejdź do głównej treści
eLearner.app
Moduł 6 · Lekcja 3 z 528/50 w kursie~10 min
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

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) to specjalna składnia, obowiązująca TYLKO wewnątrz switch.
  • v := ... wiąże wartość z typem bieżącego przypadku: wewnątrz case int, v ma typ int.
  • default przechwytuje wszystkie inne typy; tam v ma typ oryginalnego interfejsu.
  • case nil dopasowuje interfejs do typu dynamicznego zerowego.

Sprawa „Bezimienna”.

Jeśli nie potrzebujesz wpisanej wartości, możesz pominąć 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:
    // ...
}

Formularz używany, gdy trzeba po prostu rozróżnić typ, a nie działać na wartość.

Wiele typów w tym samym przypadku

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)
}

Typowy przypadek użycia: drukowanie w formacie

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)
    }
}

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

Ćwiczenie#go.m6.l3.e1
Próby: 0Ładowanie...

Zaimplementuj opis(i interfejs{}) ciąg znaków, który zwraca „int”, „string” lub „altro” w zależności od typu dynamicznego.

Ładowanie edytora...
Pokaż wskazówkę

Składnia: `switch i.(type) { case T: ... default: ... }`.

Rozwiązanie dostępne po 3 próbach

Ćwiczenie#go.m6.l3.e2
Próby: 0Ładowanie...

Napisz printVal(i interfejs{}), który używa v := i.(type) i wyświetla %d dla int, %s dla string.

Ładowanie edytora...
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

Quiz#go.m6.l3.e3
Gotowe

Która składnia uruchamia zmianę typu?

Go
switch ??? {
  case int: ...
}
Opcje odpowiedzi

Podsumowanie

  • switch v := i.(type) { case T: ... }: rozróżnia typ dynamiczny.
  • Wewnątrz obudowy pojedynczego typu, v zawiera typ obudowy.
  • case T1, T2: v zachowuje typ oryginalnego interfejsu.
  • default dla nierozwiązanych spraw; case nil dla interfejsu zerowego.
  • Brak kodu fallthrough w przełącznikach typu.
  • 1 typ → asercja typu; Ponad 2 typy → przełącznik typu.