Tok řízení s příkazy switch
Stejně jako jiné programovací jazyky jazyk Go podporuje switch
příkazy. Příkazy se používají switch
, abyste se vyhnuli řetězení více if
příkazů.
switch
Pomocí příkazů se vyhnete potížím při údržbě a čtení kódu, který obsahuje mnoho if
příkazů. Tyto příkazy také usnadňují vytváření složitých podmínek. Podívejte se na switch
příkazy v následujících částech.
Základní syntaxe přepínače
Stejně jako příkaz if
switch
podmínka nevyžaduje závorky. V nejjednodušší podobě switch
vypadá příkaz takto:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
sec := time.Now().Unix()
rand.Seed(sec)
i := rand.Int31n(10)
switch i {
case 0:
fmt.Print("zero...")
case 1:
fmt.Print("one...")
case 2:
fmt.Print("two...")
}
fmt.Println("ok")
}
Pokud spustíte předchozí kód několikrát, pokaždé se zobrazí jiný výstup. (Pokud ale kód spustíte v Go Playgroundu, dostanete pokaždé stejný výsledek. To je jedno z omezení služby.)
Vyrovná každý případ switch
příkazu, dokud nenajde shodu podmínky. Všimněte si ale, že předchozí kód nepokrývá všechny možné případy hodnot proměnných num
. Pokud num
skončí , 5
výstup programu je ok
.
Můžete být také konkrétnější o výchozím případu použití a zahrnout ho takto:
switch i {
case 0:
fmt.Print("zero...")
case 1:
fmt.Print("one...")
case 2:
fmt.Print("two...")
default:
fmt.Print("no match...")
}
Všimněte si, že pro tento default
případ nezapisujete ověřovací výraz. Hodnota i
proměnné je ověřena vůči case
příkazům a default
případ zpracovává všechny neplatné hodnoty.
Použití více výrazů
V některých případech odpovídá více než jednomu výrazu pouze jeden case
příkaz. Pokud chcete case
, aby příkaz obsahoval více než jeden výraz, oddělte výrazy čárkami (,
). Tato technika umožňuje vyhnout se duplicitnímu kódu.
Následující ukázka kódu ukazuje, jak zahrnout více výrazů.
package main
import "fmt"
func location(city string) (string, string) {
var region string
var continent string
switch city {
case "Delhi", "Hyderabad", "Mumbai", "Chennai", "Kochi":
region, continent = "India", "Asia"
case "Lafayette", "Louisville", "Boulder":
region, continent = "Colorado", "USA"
case "Irvine", "Los Angeles", "San Diego":
region, continent = "California", "USA"
default:
region, continent = "Unknown", "Unknown"
}
return region, continent
}
func main() {
region, continent := location("Irvine")
fmt.Printf("John works in %s, %s\n", region, continent)
}
Všimněte si, že hodnoty, které zahrnete do výrazů příkazu case
, odpovídají datovému typu proměnné, kterou switch
příkaz ověří. Pokud jako nový příkaz zahrnete celočíselnou case
hodnotu, program se nekompiluje.
Vyvolání funkce
A switch
může také vyvolat funkci. Z této funkce můžete zapsat case
příkazy pro možné návratové hodnoty. Například následující kód volá time.Now()
funkci. Výstup, který se vytiskne, závisí na aktuálním pracovní den.
package main
import (
"fmt"
"time"
)
func main() {
switch time.Now().Weekday().String() {
case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday":
fmt.Println("It's time to learn some Go.")
default:
fmt.Println("It's the weekend, time to rest!")
}
fmt.Println(time.Now().Weekday().String())
}
Při volání funkce z switch
příkazu můžete změnit její logiku beze změny výrazu, protože vždy ověříte, co funkce vrátí.
Funkci můžete také volat z case
příkazu. Tuto techniku použijte například ke shodě konkrétního vzoru pomocí regulárního výrazu. Tady je příklad:
package main
import "fmt"
import "regexp"
func main() {
var email = regexp.MustCompile(`^[^@]+@[^@.]+\.[^@.]+`)
var phone = regexp.MustCompile(`^[(]?[0-9][0-9][0-9][). \-]*[0-9][0-9][0-9][.\-]?[0-9][0-9][0-9][0-9]`)
contact := "foo@bar.com"
switch {
case email.MatchString(contact):
fmt.Println(contact, "is an email")
case phone.MatchString(contact):
fmt.Println(contact, "is a phone number")
default:
fmt.Println(contact, "is not recognized")
}
}
Všimněte si, že switch
blok neobsahuje žádný ověřovací výraz. Pojďme si o tomto konceptu promluvit v další části.
Vynechání podmínky
V go můžete vynechat podmínku switch
v příkazu, jako to uděláte v if
příkazu. Tento vzor se podobá porovnávání true
hodnoty, jako kdybyste příkaz vynucovali switch
tak, aby se spouštěl po celou dobu.
Tady je příklad, jak napsat switch
příkaz bez podmínky:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
r := rand.Float64()
switch {
case r > 0.1:
fmt.Println("Common case, 90% of the time")
default:
fmt.Println("10% of the time")
}
}
Program vždy spustí tento typ switch
příkazu, protože podmínka je vždy pravdivá. Podmíněný switch
blok může být snazší udržovat než dlouhý řetězec if
příkazů a else if
příkazů.
Propadne logika dalšímu případu.
V některých programovacích jazycích napíšete break
na konci každého case
příkazu klíčové slovo. Ale v Go, když logika spadá do jednoho případu, ukončí switch
blok, pokud ho explicitně nezastavíte. Pokud chcete logiku projít k dalšímu okamžitému případu, použijte fallthrough
klíčové slovo.
Pokud chcete lépe porozumět tomuto vzoru, podívejte se na následující vzorový kód.
package main
import (
"fmt"
)
func main() {
switch num := 15; {
case num < 50:
fmt.Printf("%d is less than 50\n", num)
fallthrough
case num > 100:
fmt.Printf("%d is greater than 100\n", num)
fallthrough
case num < 200:
fmt.Printf("%d is less than 200", num)
}
}
Spusťte kód a analyzujte výstup:
15 is less than 50
15 is greater than 100
15 is less than 200
Vidíte něco špatného?
Všimněte si, že protože num
je 15 (menší než 50), odpovídá prvnímu případu. Ale num
není větší než 100. A protože první case
příkaz má fallthrough
klíčové slovo, logika přejde na další case
příkaz okamžitě bez ověření případu. Proto při použití klíčového fallthrough
slova musíte být opatrní. Možná nebudete chtít chování, které tento kód vytvoří.