Middle
Kā ir strukturēti konteksti Go valodā?
sobes.tech AI
Atbilde no AI
Konteksts (context.Context) Go valodā tiek izmantots, lai nodotu informāciju par termiņiem, atcelšanu un citiem datiem starp API robežām. Tas ir koka struktūra: katrs konteksts ir bērns citam, izņemot saknes (context.Background() vai context.TODO()).
Galvenās context.Context saskarnes metodes:
Deadline() (deadline time.Time, ok bool): Atgriež konteksta termiņu.Done() <-chan struct{}: Atgriež kanālu, kas tiek aizvērts, kad konteksts tiek atcelts.Err() error: Atgriež kļūdu, kas noveda pie konteksta atcelšanas.Value(key any) any: Atgriež saistīto vērtību ar atslēgu kontekstā.
Tiek izveidots ar context pakotnes funkcijām:
context.Background(): Saknes tukšais konteksts, kas tiek izmantots kā galvenās procesa bāze.context.TODO(): Izmanto kā aizstājēju, kad nav zināms, kuru kontekstu izmantot.context.WithCancel(parent Context): Izveido bērna kontekstu un atcelšanas funkciju.context.WithDeadline(parent Context, d time.Time): Izveido bērna kontekstu ar termiņu.context.WithTimeout(parent Context, timeout time.Duration): Izveido bērna kontekstu ar laika ierobežojumu.context.WithValue(parent Context, key, val any): Izveido bērna kontekstu ar vērtību.
Galvenās Context realizācijas:
emptyCtx: Pamata, neatsaucams un bez vērtībām. Tiek izmantotsBackgroundunTODO.cancelCtx: Atbalsta atcelšanu. Sastāv no pamata konteksta un atcelšanas kanāla.timerCtx: Atbalsta termiņu/laika ierobežojumu. SaturcancelCtxun taimeri.valueCtx: Atbalsta vērtību nodošanu. Satur pamata kontekstu un atslēgas-vērtības pāri.
Kad vecā konteksts tiek atcelts, automātiski tiek atcelti visi bērni. Tas ļauj izplatīt atcelšanas signālus vai termiņus pa izsaukumu ķēdi.
Piemērs ar context.WithCancel:
package main
import (
"context"
"fmt"
"time"
)
func main() {
// Izveido saknes kontekstu un atcelšanas funkciju
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // Garantē atcelšanu, izejot no main
go func() {
select {
case <-ctx.Done(): // Gaida konteksta atcelšanu
fmt.Println("Uzdevums atcelts:", ctx.Err())
return
case <-time.After(5 * time.Second): // Vai pabeidz pēc 5 sekundēm
fmt.Println("Uzdevums pabeigts")
}
}()
// Atceļ kontekstu no citas vietas
time.Sleep(1 * time.Second)
fmt.Println("Atceļ kontekstu...")
cancel()
// Dod laiku gorutīnai apstrādāt atcelšanu
time.Sleep(100 * time.Millisecond)
}
Piemērs ar 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("Apstrādā pieprasījumu lietotāja ID:", userID)
} else {
fmt.Println("Lietotāja ID nav kontekstā")
}
}
func main() {
ctx := context.WithValue(context.Background(), userIDKey("UserID"), "12345")
processRequest(ctx)
}