switch porównuje jedną wartość z listą przypadków i wykonuje pierwszy pasujący. Inaczej niż w C, Javie i JavaScripcie przypadek w Go nie przechodzi do następnego, więc nie ma break, o którym można zapomnieć.
Przypadki są sprawdzane od góry do dołu i wykonuje się tylko pierwszy pasujący. default wykonuje się, gdy nic nie pasuje; jest opcjonalny i może stać w dowolnym miejscu listy, choć zgodnie z konwencją jest na końcu.
Wiele wartości w jednym przypadku
case "sat", "sun": pasuje do każdej z tych wartości. W ten sposób Go wyraża to, co C robi przez ułożone jeden pod drugim puste przypadki. Działa każdy porównywalny typ: stringi, liczby, rune, wartości logiczne, wskaźniki i typy nazwane, takie jak enumy:
Dwa przypadki z tą samą stałą wartością to błąd kompilacji:
./main.go:10:7: duplicate case 1 (constant of type int) in expression switch
./main.go:8:7: previous case
Switch bez warunku
Pomiń wyrażenie, a każdy przypadek stanie się testem logicznym. To czytelniejsza w Go forma długiego łańcucha if/else if:
switch { to skrót od switch true {. Ponieważ wygrywa pierwszy prawdziwy przypadek, kolejność ma znaczenie: do bmi < 25 dochodzi się tylko wtedy, gdy bmi < 18.5 było fałszywe, więc każdy przypadek może zakładać, że te powyżej nie zadziałały.
Switch z instrukcją inicjalizującą
Podobnie jak if, switch może zaczynać się od krótkiej instrukcji. Zadeklarowane w niej zmienne mają zasięg ograniczony do switch:
Instrukcję inicjalizującą można też połączyć ze switch bez wyrażenia: switch n := len(items); { case n == 0: ... }.
fallthrough
Gdy naprawdę chcesz przejść do następnego przypadku, napisz fallthrough jako ostatnią instrukcję przypadku. Przekazuje ono sterowanie do ciała następnego przypadku bez obliczania jego warunku:
Poziom 2 wypisuje write, a potem read, kumulując uprawnienia w dół. Warunki późniejszych przypadków nie są sprawdzane: po fallthrough z case 2 wykonuje się case 1, mimo że level wynosi 2.
Zasady dla fallthrough:
- Musi być ostatnią instrukcją w przypadku.
- Nie może wystąpić w ostatnim przypadku:
cannot fallthrough final case in switch. - Nie jest dozwolone w type switch.
W praktyce fallthrough rzadko występuje w kodzie Go. Wiele wartości w jednym przypadku pokrywa typową potrzebę, a jawne wywołania funkcji są zwykle czytelniejsze niż łańcuch fallthrough.
break w switch
break wewnątrz przypadku wychodzi ze switch. Przypadki kończą się same, więc potrzebujesz go tylko do wcześniejszego opuszczenia przypadku. Pułapką jest switch wewnątrz pętli:
Bez etykiety loop instrukcja break kończy switch, a pętla idzie dalej do "c". Za to continue zawsze odnosi się do otaczającej pętli, bo switch nie jest pętlą.
Switch po typach
Type switch rozgałęzia się według dynamicznego typu wartości interfejsu, używając specjalnej formy v.(type):
W przypadku z jednym typem x ma ten typ (len(x) działa w przypadku string). W przypadku z kilkoma typami x zachowuje typ interfejsu. Strona o asercjach typów szczegółowo omawia type switch i asercję v.(T).
Czym switch w Go różni się od innych
| Zachowanie | C, Java, JavaScript | Go |
|---|---|---|
| Przejście do następnego przypadku | domyślne | tylko z fallthrough |
break na końcu każdego przypadku | wymagany | niepotrzebny |
| Kilka wartości w przypadku | ułożone puste przypadki | case a, b, c: |
| Wartości przypadków | (zwykle) stałe | dowolne wyrażenie, obliczane od góry do dołu |
| Wartość w switch | typy całkowite (C) | dowolny porównywalny typ |
| Brak wyrażenia w switch | niedozwolony | switch { case cond: } |
Wyrażenia w przypadkach nie muszą być stałymi. case limit(), max + 1: jest poprawne; są obliczane po kolei, aż któreś pasuje, więc późniejsze wyrażenia mogą się nigdy nie wykonać.
Wyczerpujące pokrycie
Go nie sprawdza, czy switch po enumie obejmuje każdą wartość. Dodaj default, który loguje, zwraca błąd lub wywołuje panic dla nieoczekiwanych wartości, albo użyj lintera exhaustive (część golangci-lint), żeby brakujące przypadki były zgłaszane podczas budowania.
Najczęściej zadawane pytania
Czy switch w Go przechodzi do następnego przypadku?
Nie. Case w Go kończy się automatycznie przy następnym case; nigdy nie piszesz break, żeby go zatrzymać. Jeśli chcesz, by wykonanie przeszło do ciała następnego przypadku, napisz fallthrough jako ostatnią instrukcję przypadku. Przeskakuje bezwarunkowo, bez sprawdzania warunku następnego przypadku.
Jak dopasować kilka wartości w jednym case w Go?
Wymień je po przecinku: case "sat", "sun":. Przypadek wykona się, jeśli wartość w switch jest równa którejkolwiek z nich. To zastępuje puste, ułożone jeden pod drugim przypadki, które piszesz w C lub Javie.
Czym jest switch bez warunku w Go?
switch { case x < 0: ...; case x == 0: ...; default: ... }. Bez wyrażenia po switch każdy przypadek jest warunkiem logicznym i wykonuje się pierwszy prawdziwy. To idiomatyczny zamiennik długiego łańcucha if/else if.
Co robi break wewnątrz switch w Go?
Kończy switch, a nie otaczającą pętlę for. Rzadko jest potrzebny, bo przypadki kończą się same, ale zaskakuje osoby, które piszą break w switch wewnątrz pętli, oczekując wyjścia z pętli. Do tego użyj break z etykietą albo return.