Go dilinde bağlamlar nasıl yapılandırılmıştır?
sobes.tech yapay zeka
AI'dan gelen yanıt
Go dilinde (context.Context) bağlam, API sınırları arasında zaman aşımı, iptal ve diğer verilerin iletimi için kullanılır. Ağaç yapısı gösterir: Her bağlam, kök (context.Background() veya context.TODO()) hariç, başka bir bağlamın çocuğudur.
context.Context arayüzünün temel yöntemleri:
Deadline() (deadline time.Time, ok bool): Bağlamın zaman aşımını döndürür.Done() <-chan struct{}: Bağlam iptal edildiğinde kapanan kanalı döndürür.Err() error: Bağlamın iptaline neden olan hatayı döndürür.Value(key any) any: Bağlamdaki anahtarla ilişkili değeri döndürür.
context paketinin fonksiyonlarıyla oluşturulur:
context.Background(): Ana süreç için temel olan boş kök bağlam.context.TODO(): Hangi bağlamın kullanılacağı bilinmediğinde yer tutucu olarak kullanılır.context.WithCancel(parent Context): Çocuk bağlam ve iptal fonksiyonu oluşturur.context.WithDeadline(parent Context, d time.Time): Zaman aşımı ile çocuk bağlam oluşturur.context.WithTimeout(parent Context, timeout time.Duration): Süre aşımı ile çocuk bağlam oluşturur.context.WithValue(parent Context, key, val any): Değer ile çocuk bağlam oluşturur.
Context'in temel uygulamaları:
emptyCtx: Temel, iptal edilemez ve değer içermez.BackgroundveTODOkullanılır.cancelCtx: İptal desteği sağlar. Temel bağlam ve iptal kanalı içerir.timerCtx: Zaman aşımı veya süre sınırı destekler.cancelCtxve zamanlayıcı içerir.valueCtx: Değer iletimi sağlar. Temel bağlam ve anahtar-değer çifti içerir.
Üst bağlam iptal edildiğinde, tüm alt bağlamlar otomatik olarak iptal edilir. Bu, iptal sinyallerinin veya zaman aşımlarının zincir boyunca yayılmasını sağlar.
context.WithCancel kullanım örneği:
package main
import (
"context"
"fmt"
"time"
)
func main() {
// Kök bağlam ve iptal fonksiyonu oluştur
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // main çıkışında iptali garanti eder
go func() {
select {
case <-ctx.Done(): // Bağlam iptalini bekle
fmt.Println("Görev iptal edildi:", ctx.Err())
return
case <-time.After(5 * time.Second): // Veya 5 saniye sonra
fmt.Println("Görev tamamlandı")
}
}()
// Başka bir yerden bağlamı iptal et
time.Sleep(1 * time.Second)
fmt.Println("Bağlam iptali...")
cancel()
// İptali işleyen goroutine'e zaman tanı
time.Sleep(100 * time.Millisecond)
}
context.WithValue kullanımı örneği:
package main
import (
"context"
"fmt"
)
type userIDKey string
func processRequest(ctx context.Context) {
if userID, ok := ctx.Value(userIDKey("UserID")).(string); ok {
fmt.Println("Kullanıcı ID'si için istek işleniyor:", userID)
} else {
fmt.Println("Bağlamda kullanıcı ID'si bulunamadı")
}
}
func main() {
ctx := context.WithValue(context.Background(), userIDKey("UserID"), "12345")
processRequest(ctx)
}
Bağlamlar, çoklu iş parçacığı ortamında güvenlidir ve değiştirilemezler, bu da eşzamanlı kodlar için önemlidir. İşlevlerin ham parametrelerini iletmek yerine, işlemin yürütülmesine etki eden meta bilgileri iletmek için tasarlanmıştır.