Kontrollflöde med växelinstruktioner

Slutförd

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 5okprogrammets 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.