---
title: 'Ne Zaman Genellik'
source: 'https://academia.sh/tr/kurslar/go-tip-sistemi/ne-zaman-genellik'
course: 'Arayüzler, Hatalar ve Genellikler'
language: tr
updated: '2026-08-23T14:25:02+00:00'
license: 'CC BY-SA 4.0'
---

# Ne Zaman Genellik

Aynı toplam alan hesabı üç yazımla kuruluyor: boş arayüzle üç tip iddiası, genellikle sıfır ama T tek bir somut tipe sabitlenmiş, arayüz sözleşmesiyle yine sıfır ama farklı somut tipler aynı dilimde durabiliyor. Sınırlayıcı ölçüm, T bir arayüze sabitlendiğinde (heterojen bir koleksiyonu kabul etmek için) genelliğin kazancının kaybolduğunu gösteriyor: eleman boyutu 8 bayttan 16 bayta çıkıyor, tıpkı sıradan bir arayüz değeri gibi. Kurs on altı bağın 4'ünü bildirimde, 4'ünü kullanım yerinde, 8'ini değerin içinde buldu.

Genel Veri Yapıları dersi genelliğin üç ders boyunca hep kaynağın içinde kaldığını
gösterdi: tip parametresi ya çıkarıldı ya bildirimde açıkça yazıldı, ama hiçbir zaman
değere girmedi. Arayüz konusu tam tersini ölçmüştü — dinamik tip değerin içinde taşınıyor
ve ancak değere sorularak okunabiliyordu. Bu kapanış dersi iki yazımı, ve aralarında duran
arayüz sözleşmesini, **aynı işi üç kez yaparak** yan yana koyar: bir toplam alan hesabı
boş arayüzle, genellikle ve arayüz sözleşmesiyle kurulur, ve üçünde de bağın nerede
kurulduğu sayılır.

Kursun üçüncü iddiası buydu: genellik ile arayüz aynı işi iki ayrı yerde yapıyor.
Genellikte bağ bildirimde ve kullanım yerinde kurulur, değere hiç girmez; arayüzde bağ
değere girer. Bu ders bu farkı ilk kez doğrudan koşturarak, aynı hesaplamayı üç kez
yazarak, ölçer.

Önceki üç ders genelliği hep kendi başına ölçtü — arayüzle yan yana koymadan. Bu, kursun
genel çerçevesine bir borç bıraktı: "genellikte bağ değere girmiyor" iddiası, bir
karşılaştırma yapılmadan yalnız bir gözlemdi. Bu ders o borcu kapatıyor: aynı iş hem
genellikle hem arayüzle yazılıp aynı koşumda ölçülüyor, ve fark bir iddia olmaktan çıkıp
bir sayıya (8 bayta karşı 16 bayt) dönüşüyor.

## Aynı İş, Üç Yazım

Ölçülen iş basit: bir koleksiyondaki şekillerin toplam alanını hesaplamak. `Kare` ve
`Daire` kendi `Alan()` yöntemini taşıyor; `Sekil` arayüzü bu tek yöntemi listeliyor. Bu iş
bilinçli seçildi: alan hesabı **tipe göre gerçekten değişiyor** — bir karenin alanı
kenarın karesi, bir dairenin alanı yarıçapın karesiyle bir sabitin çarpımı — ama toplama
işleminin kendisi her tip için aynı. Üç yazımın da başarması gereken iş bu yüzden iki
parçaya ayrılıyor: tipe özgü kısım (`Alan()`in kendi gövdesi) ve tipten bağımsız kısım
(toplamı biriktirmek).

```go
// uc.go — ayni is uc yazimla: bos arayuz, genellik, arayuz sozlesmesi
package main

import (
	"fmt"
	"unsafe"
)

type Kare struct{ Kenar float64 }

func (k Kare) Alan() float64 { return k.Kenar * k.Kenar }

type Daire struct{ YariCap float64 }

func (d Daire) Alan() float64 { return 3.14159 * d.YariCap * d.YariCap }

type Sekil interface{ Alan() float64 }

// 1) bos arayuzle: her eleman icin bir tip iddiasi (tip anahtari dali) gerekiyor.
func toplamAlanAny(d []any) (toplam float64, iddiaSayisi int) {
	for _, e := range d {
		switch v := e.(type) {
		case Kare:
			iddiaSayisi++
			toplam += v.Alan()
		case Daire:
			iddiaSayisi++
			toplam += v.Alan()
		}
	}
	return
}

// 2) genellikle: govde her T icin ayni, T homojen kaldigi surece hic tip iddiasi yok.
func toplamAlanGenel[T Sekil](d []T) (toplam float64) {
	for _, e := range d {
		toplam += e.Alan()
	}
	return
}

// 3) arayuz sozlesmesiyle: farkli somut tipler ayni dilimde, hicbir tip iddiasi yok.
func toplamAlanArayuz(d []Sekil) (toplam float64) {
	for _, e := range d {
		toplam += e.Alan()
	}
	return
}

func main() {
	fmt.Println("-- ayni is, uc yazim --")

	karisik := []any{Kare{Kenar: 2}, Daire{YariCap: 1}, Kare{Kenar: 3}}
	tAny, iddia := toplamAlanAny(karisik)
	fmt.Printf("bos arayuz    toplam=%.4f  tip iddiasi=%d  bildirim satiri=0\n", tAny, iddia)

	homojen := []Kare{{Kenar: 2}, {Kenar: 3}}
	tGenel := toplamAlanGenel(homojen)
	fmt.Printf("genellik      toplam=%.4f  tip iddiasi=0  bildirim satiri=1 (kisit)\n", tGenel)

	sozlesmeli := []Sekil{Kare{Kenar: 2}, Daire{YariCap: 1}, Kare{Kenar: 3}}
	tArayuz := toplamAlanArayuz(sozlesmeli)
	fmt.Printf("arayuz        toplam=%.4f  tip iddiasi=0  bildirim satiri=1 (arayuz)\n", tArayuz)

	fmt.Println()
	fmt.Println("-- sinirlayici olcum: T bir arayuze sabitlenince kazanc kayboluyor --")
	heterojen := []Sekil{Kare{Kenar: 2}, Daire{YariCap: 1}}
	tDejenere := toplamAlanGenel(heterojen)
	fmt.Printf("toplamAlanGenel[Kare](homojen)    T=Kare   eleman boyutu=%d bayt  sonuc=%.4f\n",
		unsafe.Sizeof(homojen[0]), tGenel)
	fmt.Printf("toplamAlanGenel[Sekil](heterojen) T=Sekil  eleman boyutu=%d bayt  sonuc=%.4f\n",
		unsafe.Sizeof(heterojen[0]), tDejenere)
}
```

```
-- ayni is, uc yazim --
bos arayuz    toplam=16.1416  tip iddiasi=3  bildirim satiri=0
genellik      toplam=13.0000  tip iddiasi=0  bildirim satiri=1 (kisit)
arayuz        toplam=16.1416  tip iddiasi=0  bildirim satiri=1 (arayuz)

-- sinirlayici olcum: T bir arayuze sabitlenince kazanc kayboluyor --
toplamAlanGenel[Kare](homojen)    T=Kare   eleman boyutu=8 bayt  sonuc=13.0000
toplamAlanGenel[Sekil](heterojen) T=Sekil  eleman boyutu=16 bayt  sonuc=7.1416
```

**GN13.** İlk üç satır aynı hesaplamanın üç kaynağını karşılaştırıyor. Boş arayüz yazımı
üç elemanın üçü için de bir tip iddiası (tip anahtarının bir dalı) çalıştırıyor ve hiçbir
arayüz bildirmiyor — sözleşme kaynakta hiçbir yerde yazılı değil, yalnız `switch` içindeki
`case` dalları örtük olarak hangi tiplerin bekleneceğini söylüyor. Genellik yazımı sıfır
tip iddiasıyla çalışıyor ama `homojen` yalnız `Kare` içeriyor — `T`, Genel Veri Yapıları
dersinin ölçtüğü gibi, çağıranın bildiriminde tek bir somut tipe sabitleniyor. Arayüz
yazımı da sıfır tip iddiasıyla çalışıyor ve üstelik `Kare` ile `Daire`yi **aynı dilimde**
taşıyabiliyor — `sozlesmeli` ikisini birden içeriyor, `homojen` içeremezdi.

## Sınırlayıcı Ölçüm: T Bir Arayüze Sabitlenince Kazanç Kayboluyor

**GN14.** Son iki satır genelliğin sınırını gösteriyor. `toplamAlanGenel`, kısıtı bir
yöntem listesi olduğu için, `T`yi bir arayüz tipiyle de örnekleyebiliyor —
`toplamAlanGenel[Sekil](heterojen)` derleniyor ve `Kare` ile `Daire`yi karışık bir
dilimde kabul ediyor. Ama bunun bedeli ölçülüyor: `T=Kare` iken her eleman 8 bayt (yalnız
`Kenar` alanının kendisi), `T=Sekil` iken her eleman 16 bayt — arayüz çiftinin taşıdığı
tip işaretçisi ile veri işaretçisinin toplamı. `T`yi bir arayüze sabitlemek, genelliğin
sıfır maliyetli sözünü bozuyor: kod artık `toplamAlanArayuz`dan hiçbir farkı olmayan bir
şey çalıştırıyor, yalnız bunu bir tip parametresinin arkasına gizlemiş durumda.

`toplamAlanGenel`in gövdesi iki çağrıda da harfi harfine aynı kaldı — `for _, e := range d
{ toplam += e.Alan() }` satırı ne `T=Kare` ne `T=Sekil` için değişti. Değişen yalnız
`T`nin ne olduğu, ve bu değişim eleman boyutunu iki katına çıkardı. Bu, genelliğin
tanımının kendisinden geliyor: bir genel gövde, tek bir kaynaktan, örneklendiği her `T`
için **aynı** işlemi çalıştırır. `T=Kare` iken bu işlem `Kare.Alan()`i doğrudan, ek bir
katman olmadan çağırıyor; `T=Sekil` iken aynı işlem artık bir arayüz değeri üzerinden
dolaylı bir yöntem çağrısı yapıyor — kaynakta hiçbir satır değişmese de, çalışma zamanında
olan biten değişiyor.

Bu, kursun sorusuna kesin bir yanıt veriyor: genellik her zaman kazanmaz. Bir koleksiyonun
bütün elemanları aynı somut tipteyse ve üzerlerinde yapılan işlem her tip için aynıysa,
genellik hem sıfır tip iddiası hem sıfır ek bayt sağlıyor. Elemanlar farklı somut tipler
taşımak zorundaysa — davranış tipe göre gerçekten değişmesi gerekiyorsa — iki seçenek
kalıyor: `T`yi bir arayüze sabitleyip genelliğin kazancından vazgeçmek, ya da baştan
arayüz yazmak. İkincisi daha dürüst bir yazım, çünkü kaynak zaten neyin olacağını —
birden fazla somut tipin aynı yerde duracağını — söylüyor. Genel bir gövde, tanımı
gereği, örneklendiği her `T` için **aynı** kalıyor; farklı `T`ler için farklı davranmasını
istemek, genelliğin kendisiyle çelişiyor.

## Kurs Kapanışı

Arayüzler, Hatalar ve Genellikler kursu tek bir soruyla açıldı: Go'da bir tipin bir
arayüzü karşıladığı hiçbir yerde yazmıyor — öyleyse bu bağ nerede kuruluyor? On üç ders bu
soruyu üç düzenekte sordu: arayüzlerde (örtük gerçekleştirim, boş arayüz, tip iddiası,
gömme, tüketici tarafında tanımlama), hata değerlerinde (hata arayüzü, nöbetçi hatalar,
sarmalama, panik) ve genelliklerde (tip parametresi, tip kısıtı, genel veri yapıları, ve
bu derste üçünün karşılaştırılması).

Birinci iddia doğrulandı: on altı bağın sekizi değerin içinde taşınıyor, çünkü Go'nun
arayüz değeri bir çift — hem somut tip hem veri. İkinci iddia doğrulandı: dört bağ
kullanım yerinde kuruluyor ve kaynak, bir tipin bir arayüzü karşıladığını hiçbir yerde
söylemiyor. Üçüncü iddia bu derste doğrudan koşturuldu: genellik ile arayüz aynı işi iki
ayrı yerde yapıyor — genellikte bağ bildirimde ve kullanım yerinde kalıyor, arayüzde
değere giriyor — ve genelliğin bu kazancı, tip parametresi bir arayüze sabitlendiği anda
kayboluyor.

Bu üç düzenekten biri, "kullanım yeri", bir uyarı taşıyor: kullanım yeri derleyicinin
baktığı yerdir, kaynağın işaret ettiği yer değildir. Genel Fonksiyonlar dersi bunu
doğrudan derleyiciye sorarak — kaynağı geçici bir pakete yazıp yalnız geçip geçmediğini
okuyarak — kanıtladı; Genel Veri Yapıları ve Tip Kısıtları dersleri de aynı yöntemi
kullandı. Dolaylı bir kanıt (yalnız kaynakta bir sözleşmenin yazılı olmadığını göstermek)
ile doğrudan bir kanıt (derleyicinin nerede durduğunu koşturarak görmek) arasındaki bu
fark, kursun kendi ölçüm disiplininin bir parçası: bir ders "kullanım yerinde kuruluyor"
diyorsa, ya derleyiciyi çağırıp nerede durduğunu göstermeli, ya da kanıtın dolaylı
olduğunu açıkça yazmalıdır.

Kurs aşırı bir genelleme yapmadan kapanıyor: bu üç düzenek (bildirim, kullanım yeri,
değer) Go'nun bütün tip sistemini kapsamıyor, yalnız on üç dersin sorduğu tek soruya —
bu bağ nerede kuruluyor? — verilen yanıtları sınıflıyor. Aşağıdaki tablo bu on üç yanıtı
tek satırda topluyor; bir satır boş bırakıldı, çünkü karşılık geldiği ders bu kapanış
yazıldığı sırada henüz diskte değildi — hücre uydurulmadı.

| Ders | Ölçülen bağ | Kurulduğu yer (bildirim · kullanım yeri · değer) | Sınırlayıcı ölçüm |
|---|---|---|---|
| Arayüz Kavramı | Bir tipin bir arayüzü örtük karşılaması; küçük arayüz ilkesi | kullanım yeri (4/4/8 dağılımı burada üretildi) | Derleme zamanı uyum kanıtı bağı bildirime taşır, kanıt yokken derleyici sessiz kalır |
| Boş Arayüz ve `any` | Boş arayüzün tip bilgisini değere taşıması | değer | `nil` işaretçili arayüz `nil` değildir |
| Tip İddiası ve Tip Anahtarı | Değere sorma: iki yanıtlı iddia, tip anahtarının seçtiği dal | değer | Aynı değer hem somut hem arayüz dalına uyabilir, seçilen dal yazılış sırasına bağlı |
| Arayüz Gömme | Sözleşme bileşimi | bildirim | Gömme yalnız sözleşmeyi birleştirir, gerçekleştirimi birleştirmez |
| Arayüz Tasarımı | Aynı somut tip, tüketicilerin tanımladığı dört bağımsız arayüzü karşılıyor; kaynağında sıfır atıf var | kullanım yeri | Aynı imzalı iki ayrı adlı arayüz örtük eşdeğer olur; eşdeğerlik ancak imza ayrılınca kırılır |
| Hata Arayüzü | Hatanın örtük karşılanan bir değer olması | kullanım yeri + değer | `nil` olmayan arayüz `nil` somut değer taşıyabilir |
| Nöbetçi Hatalar | Hata kimliğinin değerde durması | değer | Kimlik değişince çağıran sessizce yanlış dala düşer, uyarı üretilmez |
| Hata Sarmalama ve Çözme | Zincirin değerde taşınması | değer | `%v` kullanmak zinciri koparır, metin aynı kalır |
| Panik ve Kurtarma | Paniğin imzada hiçbir iz bırakmaması | (bağ kurulmuyor) | Kurtarma paniği yok etmez, taşır; kurtarılan değer yazılmazsa bilgi tümüyle kaybolur |
| Genel Fonksiyonlar | Tip parametresinin çağrı yerinde çıkarılması | kullanım yeri | Kısıtsız `T` ile `==` ve `+` yazılamaz |
| Tip Kısıtları | Kısıtın tip kümesi listelemesi | bildirim | Tip kümesi terimli arayüz yalnız kısıt konumunda geçerli |
| Genel Veri Yapıları | Örneklemenin çağıranın bildiriminde durması | bildirim | Karşılaştırılabilirlik kapsayıcının alan yapısına da bağlı |
| Ne Zaman Genellik | Aynı işin üç yazımda nerede bağlandığı | (üçünün karşılaştırması) | `T` bir arayüze sabitlenince genelliğin kazancı kayboluyor |

Kurs boyunca ölçülen üç düzenek, sonuçta, tek bir alışkanlığa iniyor: bir kaynağı okurken
"bu bağın nerede kurulduğu" sorusunu sormak. Bir bildirim satırı arandığında bulunuyorsa
bağ oradadır; bulunmuyorsa iki yer kalıyor — ya derleyicinin kullanım yerinde kurduğu bir
bağ (ki bunu görmenin tek yolu derleyiciyi çağırmaktır), ya da yalnız çalışan değere
sorularak öğrenilebilecek bir bağ. Bu üç soruyu sırayla sormak, Go'nun tip sistemini
okurken kaynağın söylediğiyle söylemediğini ayırmanın ölçülebilir bir yolu.

## Özet

- Aynı toplam alan hesabı üç yazımla kuruldu: boş arayüz üç tip iddiası gerektirdi,
  genellik ve arayüz sıfır tip iddiasıyla çalıştı.
- Genellik yalnız `T` tek bir somut tipe sabitlendiğinde sıfır maliyetli kalıyor; `T` bir
  arayüze sabitlenince eleman boyutu 8 bayttan 16 bayta çıkıyor ve kazanç kayboluyor.
- Davranış tipe göre gerçekten değişmesi gerekiyorsa arayüz gerekiyor, çünkü genel bir
  gövde örneklendiği her `T` için aynı kalıyor.
- Kurs boyunca ölçülen on altı bağın dördü bildirimde, dördü kullanım yerinde, sekizi
  değerin içinde kuruldu; bu dağılım Go'nun tip sistemini değil, yalnız bu on üç dersin
  sorduğu soruyu sınıflıyor.
- Genellik ile arayüz aynı işi iki ayrı yerde yapıyor: genellikte bağ değere hiç
  girmiyor, arayüzde giriyor — ve bu fark, ne zaman hangisinin seçileceğinin ölçülebilir
  karşılığı.
