select-Anweisung in der Sprache Go
Bedingte Anweisung in der Go-Sprache
select ist eine Kontrollstruktur in Go, ähnlich der switch-Anweisung.
Die select-Anweisung kann nur für Kanaloperationen verwendet werden; jeder case muss eine Kanaloperation sein, entweder ein Senden oder ein Empfangen.
Die select-Anweisung überwacht Operationen an allen angegebenen Kanälen; sobald einer der Kanäle bereit ist, wird der entsprechende Codeblock ausgeführt.
Wenn mehrere Kanäle bereit sind, wählt die select-Anweisung zufällig einen zur Ausführung aus. Wenn keiner der Kanäle bereit ist, wird der Code im default-Block ausgeführt.
Syntax
Die Syntax der select-Anweisung in der Programmiersprache Go lautet wie folgt:
select {
case <- channel1:
// Auszuführender Code
case value := <- channel2:
// Auszuführender Code
case channel3 <- value:
// Auszuführender Code
// Sie können eine beliebige Anzahl von Fällen definieren
default:
// Code, der ausgeführt wird, wenn keiner der Kanäle bereit ist
}
Das Folgende beschreibt die Syntax der select-Anweisung:
- Jeder Fall muss ein Kanal sein.
- Alle Kanalausdrücke werden ausgewertet.
- Alle Ausdrücke, die gesendet werden, werden ausgewertet
- Wenn einer der Kanäle fortfahren kann, wird er ausgeführt; die anderen werden ignoriert.
- Wenn mehrere Fälle ausgeführt werden können, wählt select zufällig und fair einen zur Ausführung aus, und die anderen werden nicht ausgeführt.
Andernfalls:- Wenn eine default-Klausel vorhanden ist, wird sie ausgeführt.
- Wenn keine default-Klausel vorhanden ist, blockiert select, bis ein Kanal fortfahren kann; Go wird Kanäle oder Werte nicht erneut auswerten.
Beispiel
Demonstration der Anwendung der select-Anweisung:
Beispiel
import (
"fmt"
"time"
)
func main() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
time.Sleep(1 * time.Second)
c1 <- "one"
}()
go func() {
time.Sleep(2 * time.Second)
c2 <- "two"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
}
}
}
Das Ausführungsergebnis des obigen Codes ist:
received one received two
Im obigen Beispiel haben wir zwei Kanäle erstellt, c1 und c2.
Die select-Anweisung wartet auf Daten von zwei Kanälen. Wenn auf c1 Daten empfangen werden, gibt sie "received one" aus; wenn auf c2 Daten empfangen werden, gibt sie "received two" aus.
Im folgenden Beispiel definieren wir zwei Kanäle und starten zwei Goroutinen, um Daten von diesen Kanälen zu empfangen. In der main-Funktion verwenden wir eine select-Anweisung, um eine nicht blockierende Auswahl zwischen den beiden Kanälen zu treffen. Wenn kein Kanal verfügbare Daten hat, wird die Anweisung im default-Zweig ausgeführt.
Nachdem das folgende Beispiel ausgeführt wurde, empfängt es kontinuierlich Daten von den beiden Kanälen. Wenn kein Kanal verfügbare Daten hat, gibt es "no message received" aus.
Beispiel
import "fmt"
func main() {
// Zwei Kanäle definieren
ch1 := make(chan string)
ch2 := make(chan string)
// Starte zwei Goroutinen, die jeweils Daten von einem der Kanäle empfangen
go func() {
for {
ch1 <- "von 1"
}
}()
go func() {
for {
ch2 <- "von 2"
}
}()
// Verwende eine select-Anweisung, um Daten von den beiden Kanälen nicht blockierend zu empfangen
for {
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
default:
// Wenn keiner der Kanäle verfügbare Daten hat, führe die Anweisungen hier aus
fmt.Println("keine Nachricht empfangen")
}
}
}