İçeriğe geç
Muhammet Şafak
en
Diller 2 dk okuma

Go 1.18 generic'ler: uzun bekleyişin sonuna doğru

Go 1.18 ile gelen generic desteği bir dilin nasıl yeniden şekillenebileceğini gösteriyor. İlk izlenimler ve trade-off'lar.

Kapak görseli — huniden yuvarlak, kare ve altıgen metal çubuk alan tezgâh; mor kalıpta TYPE generic[T Any], gövdede GO 1.18 ve FUNCTION handle(item T) plakası

Bu yazı 4 yıl önce yazıldı — o günün koşullarını yansıtır.


Go topluluğu yıllardır generic tartışıyordu. Her büyük Go konferansında konu açılır, tasarım önerileri gelir giderdi. 1.18, Mart 2022’de çıkıyor ve bu tartışmayı somut bir cevaba kavuşturuyor. Sürüm henüz tam anlamıyla elimde değil — bu yazıyı sürüm öncesi notlar ve teknik öneri belgelerine (proposal) dayanarak yazıyorum — ama gelecek olanlar hakkında yeterince netlik var.

Generic’lerin Go’ya gelmesi yalnızca yeni bir sözdizimi eklemesi değil. Dilin temel tasarım ilkelerinden biriyle — sadelik ve açıklık — bir gerilim içinde olan bir özelliğin nasıl ustaca dengelendiğini gösteriyor.

Go neden bu kadar beklemek istedi

Go’nun generic’leri bekleten şeyi anlamak için dilin felsefesine bakmak gerekiyor. Rob Pike ve ekibi sadeliği baş ilke olarak seyretti. Generic’ler, çoğu dilde tür sistemi karmaşıklığını önemli ölçüde artıran bir özelliktir. C++ template’leri, Java ve C#‘ın generic implementasyonları hem derleme süresine hem de hata mesajlarının okunabilirliğine ciddi yük bindiriyor.

Go ekibinin asıl sorusu buydu: generic’leri ekleyelim ama dilin sadeliğini bozmayalım. Yıllarca süren tasarım çalışması bu dengeyi bulmaya harcandı. Sonuçta çıkan çözüm — type parameter’lar ve interface constraint’ler — bu dengeyi oldukça iyi tutuyor gibi görünüyor.

Type parameter sözdizimi

1.18’deki sözdizimi köşeli parantez kullanıyor. Bir örnek:

func Map[T, U any](s []T, f func(T) U) []U {
    result := make([]U, len(s))
    for i, v := range s {
        result[i] = f(v)
    }
    return result
}

Bu fonksiyon herhangi bir dilim (slice) üzerinde çalışıyor. Daha önce bu tür bir soyutlama için ya interface{} kullanmak ya da her tür için ayrı fonksiyon yazmak gerekiyordu. İkisi de hoş değildi.

Constraint’ler için mevcut interface sistemi genişletildi:

type Number interface {
    int | int64 | float64
}

func Sum[T Number](s []T) T {
    var total T
    for _, v := range s {
        total += v
    }
    return total
}

Type union ile constraint tanımlamak, daha güvenli ve açık bir yapı sunuyor. “Bu fonksiyon int ya da float64 alır” ifadesi artık kod içinde açıkça yaşıyor.

Ne kazanıyoruz, ne kaybediyoruz

Kazanç tarafı belirgin: boilerplate kod azalıyor. Sıralama, filtreleme, dönüşüm gibi evrensel koleksiyon işlemleri artık tek bir tanımla yazılabiliyor. Standart kütüphane de zamanla bu yapıyı kullanmaya başlayacak.

Öte yandan, kaybetme riski taşıdığımız şeyler de var. Generic’ler kodun okunabilirliğini zorlaştırabilir — özellikle constraint’ler karmaşıklaştığında. Java dünyasında “generic cehennemi” diye anılan, iç içe type parameter’ların tip hatası mesajlarını çözülmez hale getirdiği durumlar yaşandı. Go’nun tasarımı bunu engelliyor mu? Kısmen. Ama gereğinden karmaşık constraint’ler yazmak mümkün.

Derleme süresi de tartışmalı. Başlangıçta performans kayıpları raporlandı; bu kısmen beklenen bir şey, zaman içinde iyileşecek.

Pratikte ne zaman kullanacağım

Generic’leri her yerde kullanmayı planlamıyorum. Go’nun güçlü yanlarından biri okunabilirlik; bir fonksiyona type parameter eklemek her zaman okunabilirliği artırmıyor. Koleksiyon yardımcı fonksiyonları, veri dönüşüm işlemleri, tip güvenli veri yapıları (stack, queue, set) — bunlar generic’in değer yarattığı yerler.

Ekip kodunda ise daha temkinli olacağım. Generic’lerin değerini görmek için ekibin kavramı özümsemesi gerekiyor; hemen her yere yaymak, “bu neden böyle?” sorusunu artırır.

Sürüm ellere geçtikçe topluluktan gerçek deneyimler gelecek. O noktada bu ilk izlenimleri revize etmek gerekecek. Şimdilik söyleyebildiğim şu: Go 1.18, dilin on yıllık tarihindeki en anlamlı değişikliği getiriyor ve bu değişikliğin nasıl ustaca yapıldığı, dil tasarımı açısından ilginç bir ders.

Bu konudaki deneyler

Uygulama ile sağlayıcı arasında duran, tek OpenAI uyumlu API sunan ve isteğe RAG bağlamını kendisi ekleyen self-hosted Go gateway.

Şu an ne yapıyor

Uygulamanın tek bir OpenAI uyumlu uca konuşmasını, isteğin hangi modele gideceğini ve — bir doküman havuzu bağlıysa — hangi dokümanlardan bağlam alacağını projenin ayarının belirlemesini sağlıyor. Sağlayıcı anahtarını uygulamalara dağıtmak istemeyen ve harcamayı proje başına sınırlamak isteyen herkes kendi sunucusunda çalıştırabilir.

Open-Source Web Go PostgreSQL pgvector +8 daha
Ağustos 2026 — Eylül 2026

Dile özgü serileştirme yerine dondurulmuş bir JSON zarfı; polyglot kuyruk standardı BabelQueue'ya dönüştü.

Şu an ne yapıyor

Dondurulmuş JSON zarfı dört dilde — PHP, Python, Go, Node.js — aynı baytları okutuyor; sidecar ya da broker eklentisi gerekmiyor. Polyglot kuyruk kuran ekipler spesifikasyonu ve SDK'ları bugün kullanabilir.

Open-Source JSON Redis RabbitMQ +4 daha
Mart 2026 — Haziran 2026

Yorumlar

Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.

İlgili Yazılar

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi