Tok řízení s příkazy switch

Dokončeno

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 ifswitch 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čí , 5vý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ří.