Hoe zijn de contexten opgebouwd in de Go-taal?
sobes.tech AI
Antwoord van AI
De (context.Context) in Go wordt gebruikt om informatie over deadlines, annuleringen en andere gegevens tussen API-grenzen te verzenden. Het vertegenwoordigt een boom: elke context is een kind van een andere, behalve de wortel (context.Background() of context.TODO()).
De belangrijkste methoden van de interface context.Context:
Deadline() (deadline time.Time, ok bool): Geeft de deadline van de context terug.Done() <-chan struct{}: Geeft een kanaal dat wordt gesloten wanneer de context wordt geannuleerd.Err() error: Geeft de fout terug die tot de annulering van de context heeft geleid.Value(key any) any: Geeft de waarde terug die aan de sleutel in de context is gekoppeld.
Ze worden gemaakt met functies uit de context-package:
context.Background(): De lege hoofdkontekst, gebruikt als basis voor het hoofdproces.context.TODO(): Wordt gebruikt als tijdelijke aanduiding wanneer niet bekend is welke context te gebruiken.context.WithCancel(parent Context): Maakt een kindcontext en een annuleringsfunctie.context.WithDeadline(parent Context, d time.Time): Maakt een kindcontext met een deadline.context.WithTimeout(parent Context, timeout time.Duration): Maakt een kindcontext met een timeout.context.WithValue(parent Context, key, val any): Maakt een kindcontext met een waarde.
Belangrijkste implementaties van Context:
emptyCtx: Basis, niet-annuleerbaar en zonder waarden. GebruiktBackgroundenTODO.cancelCtx: Ondersteunt annulering. Bestaat uit een basiscontext en een annuleringskanaal.timerCtx: Ondersteunt deadline/timeout. BevatcancelCtxen een timer.valueCtx: Ondersteunt het doorgeven van waarden. Bevat een basiscontext en sleutel-waardeparen.
Bij annulering van de oudercontext worden alle kindcontexten automatisch geannuleerd. Dit maakt het mogelijk om annulering- of deadline-signalen door te geven in de keten van oproepen.
Voorbeeld van gebruik van context.WithCancel:
package main
import (
"context"
"fmt"
"time"
)
func main() {
// Maak de hoofdkontekst en een annuleringsfunctie
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // Zorg voor annulering bij het verlaten van main
go func() {
select {
case <-ctx.Done(): // Wacht op annulering van de context
fmt.Println("Taak geannuleerd:", ctx.Err())
return
case <-time.After(5 * time.Second): // Of na 5 seconden
fmt.Println("Taak voltooid")
}
}()
// Annuleer de context vanaf een andere plek
time.Sleep(1 * time.Second)
fmt.Println("Annuleren van de context...")
cancel()
// Geef de goroutine tijd om de annulering te verwerken
time.Sleep(100 * time.Millisecond)
}
Voorbeeld van gebruik van context.WithValue:
package main
import (
"context"
"fmt"
)
type userIDKey string
func processRequest(ctx context.Context) {
if userID, ok := ctx.Value(userIDKey("UserID")).(string); ok {
fmt.Println("Verwerking van verzoek voor User ID:", userID)
} else {
fmt.Println("User ID niet gevonden in context")
}
}
func main() {
ctx := context.WithValue(context.Background(), userIDKey("UserID"), "12345")
processRequest(ctx)
}
Contexten zijn thread-safe en onveranderlijk, wat belangrijk is voor gelijktijdige code. Ze zijn niet bedoeld om rauwe parameters van functies door te geven, maar eerder voor metadata die de uitvoering van het proces beïnvloeden.