Junior
Was ist der Kontext in Go?
sobes.tech KI
Antwort von AI
Der Kontext (context.Context) in Go ist ein Objekt, das eine Frist, ein Abbruchsignal und spezifische Daten für die Anfrage trägt. Er wird verwendet, um den Lebenszyklus von Goroutines zu verwalten und Informationen zwischen ihnen während der Ausführung einer Anfrage/Operation zu übertragen.
Hauptmerkmale:
- Gleichzeitig sicher: Kann sicher zwischen Goroutines übertragen werden.
- Unveränderlich: Einmal erstellt, kann ein
Contextnicht geändert werden. Abgeleitete Kontexte werden auf Basis des Elternteils erstellt. - Hierarchisch: Kontexte bilden einen Baum mit Wurzel (
context.Background()odercontext.TODO()). Das Abbrechen des Elternkontexts führt zum Abbruch aller Kindkontexte.
Hauptfunktionen des Pakets context:
context.Background(): Leerer Kontext, der in der main-Funktion, bei hochrangigen Anfragen oder beim Testen verwendet wird. Wird niemals abgebrochen.context.TODO(): Ebenfalls ein leerer Kontext. Wird als Platzhalter verwendet, wenn nicht bekannt ist, welcher Kontext verwendet werden soll, oder wenn die Funktionalität des Kontexts noch nicht implementiert ist.context.WithCancel(parent Context): Gibt einen neuen Kindkontext und eine Abbruchfunktion zurück. Das Aufrufen der Abbruchfunktion bricht diesen Kontext und alle seine Kindkontexte ab.context.WithDeadline(parent Context, deadline time.Time): Gibt einen Kindkontext zurück, der automatisch abgebrochen wird, wenn die angegebene Zeit erreicht ist. Gibt auch eine Abbruchfunktion für manuelles Abbrechen zurück.context.WithTimeout(parent Context, timeout time.Duration): Das gleiche wieWithDeadline, aber mit Angabe einer Dauer.context.WithValue(parent Context, key, val interface{}): Gibt einen Kindkontext mit einem Wert für einen Schlüssel zurück.
Anwendungen:
- Operationen abbrechen: Zum Beispiel, Timeout bei einer HTTP-Anfrage oder Unterbrechung einer längeren Operation.
- Daten übertragen: Zum Beispiel, Anforderungs-ID für das Logging, Authentifizierungsinformationen.
Beispiel für die Verwendung von context.WithTimeout:
package main
import (
"context"
"fmt"
"time"
)
func longRunningOperation(ctx context.Context, resultChan chan string) {
select {
case <-time.After(3 * time.Second):
// Operation erfolgreich abgeschlossen
resultChan <- "Operation abgeschlossen"
case <-ctx.Done():
// Kontext wurde abgebrochen
err := ctx.Err() // Grund für den Abbruch erhalten
resultChan <- fmt.Sprintf("Operation abgebrochen: %v", err)
}
}
func main() {
// Erstellen eines Kontexts mit 2 Sekunden Timeout
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel() // Sicherstellen, dass die Abbruchfunktion aufgerufen wird
resultChan := make(chan string, 1)
go longRunningOperation(ctx, resultChan)
// Warten auf Ergebnis oder Abbruch
select {
case res := <-resultChan:
fmt.Println(res)
case <-ctx.Done():
fmt.Printf("Hauptkontext beendet: %v\n", ctx.Err())
}
// Kurzes Warten, damit die Goroutine bei Abbruch beendet werden kann
time.Sleep(1 * time.Second)
}
In diesem Beispiel überprüft longRunningOperation, ob der Kontext abgebrochen wurde. Wenn der Timeout des Hauptkontexts (2 Sekunden) vor Abschluss der Operation (3 Sekunden) eintritt, erhält die Goroutine das Abbruchs-Signal über ctx.Done() und beendet sich.