Kontrollflöde med växelinstruktioner
Precis som andra programmeringsspråk har Go stöd för switch
instruktioner. Du använder switch
instruktioner för att undvika att länka flera if
instruktioner. Med hjälp switch
av instruktioner undviker du svårigheten att underhålla och läsa kod som innehåller många if
instruktioner. Dessa instruktioner gör också komplicerade villkor enklare att konstruera. Ta en titt på switch
instruktioner i följande avsnitt.
Grundläggande växelsyntax
Precis som -instruktionen if
kräver villkoret switch
inte parenteser. I sin enklaste form ser en switch
instruktion ut så här:
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")
}
Om du kör föregående kod flera gånger visas olika utdata varje gång. (Men om du kör koden i Go Playground får du samma resultat varje gång. Det är en av tjänstens begränsningar.)
Go jämför varje fall av -instruktionen switch
tills den hittar en matchning för villkoret. Observera dock att den tidigare koden inte täcker alla möjliga fall av num
variabelvärden. Om num
det slutar med är 5
ok
programmets utdata .
Du kan också vara mer specifik om standardanvändningsfallet och inkludera det så här:
switch i {
case 0:
fmt.Print("zero...")
case 1:
fmt.Print("one...")
case 2:
fmt.Print("two...")
default:
fmt.Print("no match...")
}
Observera att för ärendet default
skriver du inte ett valideringsuttryck. Värdet för variabeln i
verifieras mot -uttrycken case
och fallet default
hanterar eventuella ovaliderade värden.
Använda flera uttryck
Ibland matchar mer än ett uttryck bara en case
-instruktion. Om du vill att en case
-instruktion ska innehålla fler än ett uttryck i Go separerar du uttrycken med kommatecken (,
). Med den här tekniken kan du undvika duplicerad kod.
Följande kodexempel visar hur du inkluderar flera uttryck.
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)
}
Observera att de värden som du inkluderar i uttrycken för -instruktionen case
motsvarar datatypen för variabeln som -instruktionen switch
validerar. Om du inkluderar ett heltalsvärde som en ny case
instruktion kompileras inte programmet.
Anropa en funktion
En switch
kan också anropa en funktion. Från den funktionen kan du skriva case
instruktioner för möjliga returvärden. Följande kod anropar time.Now()
till exempel funktionen. Vilka utdata som skrivs ut beror på den aktuella veckodagen.
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())
}
När du anropar en funktion från en switch
-instruktion kan du ändra dess logik utan att ändra uttrycket eftersom du alltid verifierar vad funktionen returnerar.
Du kan också anropa en funktion från en case
-instruktion. Använd till exempel den här tekniken för att matcha ett visst mönster med hjälp av ett reguljärt uttryck. Här är ett exempel:
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")
}
}
Observera att switch
blocket inte har något valideringsuttryck. Nu ska vi prata om det konceptet i nästa avsnitt.
Utelämna ett villkor
I Go kan du utelämna ett villkor i en switch
instruktion som du gör i en if
-instruktion. Det här mönstret är som att jämföra ett true
värde som om du tvingade instruktionen switch
att köras hela tiden.
Här är ett exempel på hur du skriver en switch
instruktion utan villkor:
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")
}
}
Programmet kör alltid den här typen av switch
-instruktion eftersom villkoret alltid är sant. Ett villkorsblock switch
kan vara enklare att underhålla än en lång kedja med if
- och else if
-instruktioner.
Gör så att logiken hamnar i nästa ärende
I vissa programmeringsspråk skriver du ett break
nyckelord i slutet av varje case
instruktion. Men i Go, när logiken hamnar i ett fall, avslutas switch
blocket om du inte uttryckligen stoppar det. Använd nyckelordet fallthrough
för att få logiken att falla igenom i nästa omedelbara ärende.
Om du vill förstå det här mönstret bättre kan du titta på följande kodexempel.
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)
}
}
Kör koden och analysera utdata:
15 is less than 50
15 is greater than 100
15 is less than 200
Ser du något fel?
Observera att eftersom num
är 15 (mindre än 50) matchar det första fallet. Men num
är inte större än 100. Och eftersom den första case
-instruktionen har ett fallthrough
nyckelord går logiken till nästa case
-instruktion omedelbart utan att verifiera ärendet. Så du måste vara försiktig när du använder nyckelordet fallthrough
. Du kanske inte vill ha det beteende som den här koden skapar.