Przepływ sterowania z instrukcjami przełącznika

Ukończone

Podobnie jak w przypadku innych języków programowania język Go obsługuje switch instrukcje. Instrukcje służą switch do unikania tworzenia łańcuchów wielu if instrukcji. Korzystając z switch instrukcji, unikasz trudności z konserwowania i odczytywania kodu, który zawiera wiele if instrukcji. Te instrukcje ułatwiają również konstruowanie skomplikowanych warunków. Zapoznaj się z switch instrukcjami w poniższych sekcjach.

Podstawowa składnia przełącznika

Podobnie jak w przypadku instrukcji if switch warunek nie wymaga nawiasów. W najprostszej formie switch instrukcja wygląda następująco:

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")
}

Jeśli uruchomisz poprzedni kod kilka razy, za każdym razem zobaczysz inne dane wyjściowe. (Jeśli jednak uruchomisz kod w środowisku Go Playground, za każdym razem uzyskasz ten sam wynik. Jest to jedno z ograniczeń usługi.

Funkcja Go porównuje każdy przypadek instrukcji switch , dopóki nie znajdzie dopasowania warunku. Zwróć jednak uwagę, że poprzedni kod nie obejmuje wszystkich możliwych przypadków num wartości zmiennych. Jeśli num kończy się to 5, dane wyjściowe programu to ok.

Bardziej szczegółowe informacje na temat domyślnego przypadku użycia można również uwzględnić w następujący sposób:

switch i {
case 0:
    fmt.Print("zero...")
case 1:
    fmt.Print("one...")
case 2:
    fmt.Print("two...")
default:
    fmt.Print("no match...")
}

Zwróć uwagę, że w przypadku przypadku wyrażenia default sprawdzania poprawności nie jest zapisywane. Wartość zmiennej i jest weryfikowana względem instrukcji case , a default przypadek obsługuje wszelkie niewalidowane wartości.

Używanie wielu wyrażeń

Czasami więcej niż jedno wyrażenie pasuje tylko do jednej case instrukcji. Jeśli w języku Go chcesz case , aby instrukcja zawierała więcej niż jedno wyrażenie, rozdziel wyrażenia przecinkami (,). Ta technika pozwala uniknąć duplikowania kodu.

Poniższy przykładowy kod pokazuje, jak dołączyć wiele wyrażeń.

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)
}

Zwróć uwagę, że wartości uwzględnione w wyrażeniach instrukcji case odpowiadają typowi danych zmiennej, która jest weryfikowana przez switch instrukcję. Jeśli dołączysz wartość całkowitą jako nową case instrukcję, program nie będzie kompilowany.

Wywoływanie funkcji

Element switch może również wywołać funkcję. Z tej funkcji można pisać case instrukcje dla możliwych wartości zwracanych. Na przykład poniższy kod wywołuje time.Now() funkcję . Dane wyjściowe, które są wyświetlane, zależą od bieżącego dnia tygodnia.

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())
}

Podczas wywoływania funkcji z switch instrukcji można zmodyfikować jej logikę bez zmiany wyrażenia, ponieważ zawsze sprawdzasz, co funkcja zwraca.

Ponadto można wywołać funkcję z instrukcji case . Użyj tej techniki, na przykład, aby dopasować określony wzorzec przy użyciu wyrażenia regularnego. Oto przykład:

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")
    }
}

Zwróć uwagę, że switch blok nie ma wyrażenia sprawdzania poprawności. Porozmawiajmy o tej koncepcji w następnej sekcji.

Pomiń warunek

W języku Go można pominąć warunek w switch instrukcji, takiej jak w instrukcji if . Ten wzorzec przypomina porównywanie true wartości, tak jak w przypadku wymuszania switch uruchomienia instrukcji przez cały czas.

Oto przykład sposobu pisania switch instrukcji bez warunku:

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 zawsze uruchamia instrukcję tego typu, switch ponieważ warunek jest zawsze spełniony. Blok warunkowy switch może być łatwiejszy do utrzymania niż długi łańcuch instrukcji if i else if .

Upadek logiki do następnego przypadku

W niektórych językach programowania pisze się break słowo kluczowe na końcu każdej case instrukcji. Ale w języku Go, gdy logika wchodzi w jeden przypadek, zamyka switch blok, chyba że jawnie go zatrzymasz. Aby logika przeszła do następnego natychmiastowego przypadku, użyj słowa kluczowego fallthrough .

Aby lepiej zrozumieć ten wzorzec, zapoznaj się z poniższym przykładem kodu.

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)
    }
}

Uruchom kod i przeanalizuj dane wyjściowe:

15 is less than 50
15 is greater than 100
15 is less than 200

Czy widzisz coś złego?

Zwróć uwagę, że ponieważ num wartość jest 15 (mniejsza niż 50), jest zgodna z pierwszym przypadkiem. Ale num nie jest większy niż 100. Ponieważ pierwsza case instrukcja ma fallthrough słowo kluczowe, logika przechodzi natychmiast do następnej case instrukcji bez sprawdzania poprawności przypadku. Dlatego podczas używania słowa kluczowego fallthrough należy zachować ostrożność. Możesz nie chcieć zachowania tworzonego przez ten kod.