Suche…


Einführung

Das Schlüsselwort select bietet eine einfache Methode, um mit Kanälen zu arbeiten und erweiterte Aufgaben auszuführen. Es wird häufig für verschiedene Zwecke verwendet: - Timeouts behandeln. - Wenn es mehrere Kanäle gibt, aus denen gelesen werden kann, wird die Auswahl zufällig von einem Kanal gelesen, der Daten enthält. - Eine einfache Möglichkeit zu definieren, was passiert, wenn auf einem Kanal keine Daten verfügbar sind.

Syntax

  • wählen {}
  • Wählen Sie {case true:}
  • select {case incomingData: = <-someChannel:}
  • Wählen Sie {default:}

Einfach auswählen Mit Kanälen arbeiten

In diesem Beispiel erstellen wir eine Goroutine (eine Funktion, die in einem separaten Thread ausgeführt wird), die einen chan Parameter akzeptiert und einfach Schleifen durchführt, wobei jedes Mal Informationen in den Kanal gesendet werden.

In der main wir eine for Schleife und eine select . Die select blockiert die Verarbeitung, bis eine der case Anweisungen wahr ist. Hier haben wir zwei Fälle erklärt; Der erste ist, wenn Informationen durch den Kanal kommen, und der andere ist, wenn kein anderer Fall auftritt, was als default .

// Use of the select statement with channels (no timeouts)
package main

import (
    "fmt"
    "time"
)

// Function that is "chatty"
// Takes a single parameter a channel to send messages down
func chatter(chatChannel chan<- string) {
    // Clean up our channel when we are done.
    // The channel writer should always be the one to close a channel.
    defer close(chatChannel)

    // loop five times and die
    for i := 1; i <= 5; i++ {
        time.Sleep(2 * time.Second) // sleep for 2 seconds
        chatChannel <- fmt.Sprintf("This is pass number %d of chatter", i)
    }
}

// Our main function
func main() {
    // Create the channel
    chatChannel := make(chan string, 1)

    // start a go routine with chatter (separate, non blocking)
    go chatter(chatChannel)

    // This for loop keeps things going while the chatter is sleeping
    for {
        // select statement will block this thread until one of the two conditions below is met
        // because we have a default, we will hit default any time the chatter isn't chatting
        select {
        // anytime the chatter chats, we'll catch it and output it
        case spam, ok := <-chatChannel:
            // Print the string from the channel, unless the channel is closed
            // and we're out of data, in which case exit.
            if ok {
                fmt.Println(spam)
            } else {
                fmt.Println("Channel closed, exiting!")
                return
            }
        default:
            // print a line, then sleep for 1 second.
            fmt.Println("Nothing happened this second.")
            time.Sleep(1 * time.Second)
        }
    }
}

Versuchen Sie es auf dem Go Playground!

Select mit Timeouts verwenden

Hier habe ich die for Schleifen entfernt und ein Timeout vorgenommen, indem der select einen zweiten case hinzugefügt hat, der nach 3 Sekunden zurückkehrt. Da die select nur wartet, bis JEDER Fall erfüllt ist, wird der zweite case ausgelöst, und dann endet unser Skript, und chatter() erhält niemals eine Chance, es zu beenden.

// Use of the select statement with channels, for timeouts, etc.
package main

import (
    "fmt"
    "time"
)

// Function that is "chatty"
//Takes a single parameter a channel to send messages down
func chatter(chatChannel chan<- string) {
    // loop ten times and die
    time.Sleep(5 * time.Second) // sleep for 5 seconds
    chatChannel<- fmt.Sprintf("This is pass number %d of chatter", 1)
}

// out main function
func main() {
    // Create the channel, it will be taking only strings, no need for a buffer on this project
    chatChannel := make(chan string)
    // Clean up our channel when we are done
    defer close(chatChannel)

    // start a go routine with chatter (separate, no blocking)
    go chatter(chatChannel)

    // select statement will block this thread until one of the two conditions below is met
    // because we have a default, we will hit default any time the chatter isn't chatting
    select {
    // anytime the chatter chats, we'll catch it and output it
    case spam := <-chatChannel:
        fmt.Println(spam)
    // if the chatter takes more than 3 seconds to chat, stop waiting
    case <-time.After(3 * time.Second):
        fmt.Println("Ain't no time for that!")
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow