Generic — genel türlerin özü ve T parametreleri

Yazar: IT Sectr Yayınlanma: 2026-06-18 Okuma süresi: 10 dk

Generic (genel programlama) — Swift'te, parametrelendirilmiş bir tür ile türler ve işlevler yazmayı sağlayan bir mekanizmadır. Int, String ve özel yapılar için kodu çoğaltmak yerine, geliştirici her türle çalışan, aynı zamanda sıkı tür denetimini koruyan tek bir genel çözüm oluşturur. Derleyici, kullanım noktasında somut türü yerleştirir ve performans kaybı olmadan güvenlik sağlar. Swift Book, 2025'e göre, genel parametreler dilin temel özelliklerinden biridir ve standart kütüphane ile SwiftUI'nin temelini oluşturur.

Ana Noktalar

  • Generic — tür parametreleri ile genel programlama mekanizması
  • İşlevler genel parametrelerle kod çoğaltmadan her türle çalışır
  • where kısıtlamaları genel türlerin kapsamını koşulları karşılayan türlerle sınırlar
  • Associated Types protokollerde protokollerin genel olmasını sağlar
  • Derleyici her somut tür için özelleştirilmiş kod üretir

Swift'te Generic Nedir?

Generic (genel tür) — Swift'te, tür parametrelendirmesiyle esnek, yeniden kullanılabilir kod yazmayı sağlayan bir sözdizimsel yapıdır. Somut bir tür yerine, açılı parantezler içinde bir yer tutucu yazılır — genellikle , ancak herhangi bir ad kullanılabilir. Generics, SwiftUI'nin (View, some View), standart kütüphanenin (Array, Optional) ve Combine'ın temelini oluşturur.

Generics Neden Gereklidir

Generics olmadan, her tür için ayrı işlevler yazmak gerekirdi: swapInts, swapStrings, swapDates. Tek bir genel swap işlevi, üç değişkeni de tek bir bildirimle değiştirir. Bu, çoğaltmayı azaltır, okunabilirliği artırır ve kod kopyalarken hata olasılığını düşürür.

swift
func swapValues<T>(_ a: inout T, _ b: inout T) {
    let temp = a
    a = b
    b = temp
}

var x = 10
var y = 20
swapValues(&x, &y)

Swift derleyicisi, bir generic'in her somut kullanımı için özelleştirilmiş kod üretir. Bu, swapValues genel işlevinin, Int için elle yazılmış bir işleve kıyasla ek yükü olmadığı anlamına gelir. Swift, Java gibi tür silme kullanmaz — generics hem derleme zamanında hem de çalışma zamanında bulunur (ancak optimizasyon bunları özelleştirebilir).

T Parametresiyle Genel İşlevler

Genel işlevler, bir veya daha fazla tür parametresini kabul eden işlevlerdir. Tür parametreleri, işlev adından sonra açılı parantezler içinde belirtilir: . Bunlar imzada kullanılabilir: bağımsız değişken türü, dönüş türü ve işlev gövdesi içinde.

Çoklu Tür Parametreleri

Bir işlev çoklu genel parametreye sahip olabilir. Örneğin, findKey işlevi, K anahtarları ve V değerleri olan bir sözlük alır. Her tür parametresi benzersizdir ve kısıtlamalarda kullanılabilir.

swift
func findKey<K: Hashable, V>(
    for value: V,
    in dictionary: [K: V]
) -> K? where V: Equatable {
    for (key, dictValue) in dictionary {
        if dictValue == value {
            return key
        }
    }
    return nil
}

K: Hashable ve where V: Equatable kısıtlamaları, findKey'in yalnızca anahtarları hashlenebilir ve değerleri karşılaştırılabilir olan bir sözlükle çağrılabilmesini sağlar. Bu tür kısıtlamalar bürokrasi değil, bir gerekliliktir: Hashable olmadan anahtar araması indekslenemez, Equatable olmadan value ile dictValue karşılaştırılamaz.

where ile Tür Kısıtlamaları

where — Swift'te genel parametrelere ek kısıtlamalar getiren bir anahtar kelimedir. Açılı parantezler içinde basitçe bir protokol belirtmenin () aksine, where daha karmaşık koşulları ifade etmeye olanak tanır: birden çok protokole uygunluk, tür parametreleri arasındaki ilişkiler ve associated type'ların iyileştirilmesi.

where Sözdizimi

where cümlesi, işlev veya tür imzasından sonra, açılı küme parantezinden önce yazılır. where içinde T: Comparable & Hashable (aynı anda iki protokole uygunluk) veya T.U == Int (bir associated type'ı somutlaştırma) belirtilebilir.

swift
protocol Container {
    associatedtype Item
    mutating func append(_ item: Item)
    var count: Int { get }
}

extension Container where Item: Comparable {
    func isSorted() -> Bool {
        // Implementation available only if Item: Comparable
        return true
    }
}

where ile uzantı, koşulu karşılayan türler için yöntemler ekler. Container, isSorted yöntemini alırken, Container almaz çünkü Any Comparable değildir. Bu, koşullu işlevsellik için güçlü bir mekanizmadır.

Protokollerde Associated Types

Associated Types (ilişkili türler) — bir protokolü bildirim aşamasında somut bir tür belirtmeden genel hale getirmenin bir yoludur. yerine, protokol bir associatedtype bildirir ve bu, uygulamada somutlaştırılır. Bu özellikle koleksiyonlar için önemlidir: Sequence protokolü, dizinin hangi öğeleri içereceğini bilmez.

where ile Associated Types Bağlantısı

where kullanarak farklı protokollerin associated type'ları arasında ilişkiler kurulabilir. Örneğin, bir protokolün Item'ının diğerinin Iterator.Element'iyle eşleşmesi istenebilir. Bu, derleyici düzeyinde tür uyumluluğunu garanti eder.

swift
protocol StackProtocol {
    associatedtype Element
    mutating func push(_ item: Element)
    mutating func pop() -> Element?
}

struct IntStack: StackProtocol {
    typealias Element = Int
    private var items: [Int] = []
    
    mutating func push(_ item: Int) { items.append(item) }
    mutating func pop() -> Int? { items.popLast() }
}

IntStack, typealias kullanarak Element'i Int olarak somutlaştırır. Derleyici, protokolün tüm gereksinimlerinin bu türle karşılandığını doğrular. Associated type'lar olmadan, genel bir protokolle StackProtocol yazmak gerekirdi, ancak Swift, Objective-C köprüleriyle tutarlılık ve daha iyi okunabilirlik için associated type'ları kullanır.

Uzantılarda ve Alt Simgelerde Generic

Genel uzantılar, ek kısıtlamalarla genel bir türe yöntem eklemeye olanak tanır. Bu, bir türün yalnızca belirli koşullarda işlevsellik kazandığı “koşullu uygunluk” modelidir. Alt simgeler de genel olabilir.

Genel Alt Simge

Bir alt simge genel olabilir: açılı parantezler içinde genel parametreleri kabul eder. Bu, dizinin farklı türlerde olabileceği durumlarda, rastgele dizinlerle koleksiyonlara güvenli erişim için kullanışlıdır.

swift
extension Array where Element: Numeric {
    func sum() -> Element {
        return reduce(0, +)
    }
}

extension Array {
    subscript<Indices: Sequence>(indices: Indices) -> [Element]
        where Indices.Element == Int {
        return indices.map { self[$0] }
    }
}

Bu yapı güçlü bir bileşim sağlar: sum yöntemi yalnızca sayısal dizilerde görünür ve rastgele dizinlerle alt simge, tamsayı dizinlerinin herhangi bir dizisiyle çalışır. Derleyici, where koşullarına göre bu üyelerin görünürlüğünü yönetir.

Generic ile Çalışırken Sık Yapılan Hatalar

Hatalar, genellikle yanlış kısıtlamalar veya somut bir türün gerekli olduğu yerde genel kullanma girişimiyle ilgilidir. Geliştiricilerin karşılaştığı üç yaygın senaryoyu inceleyelim.

Aşırı Parametrelendirme

Somut bir türün yeterli olduğu yere genel parametreler eklemek bir anti-kalıptır. Bir işlev her zaman String ile çalışıyorsa, onu yapmaya gerek yoktur. Bu, kodun gereksiz yere karmaşıklaşmasına neden olur. Generics, tür gerçekten değiştiğinde haklıdır, soyut “gelecek esnekliği” için değil.

where Kısıtlaması Eksikliği

Yöntemin var olduğunu belirtmeden genel bir parametrede yöntem çağırmak bir hatadır. T: Collection belirtilmezse .count çağıramaz. Tür parametrelerine her zaman kısıtlamalar ekleyin, aksi takdirde derleyici kodu reddeder.

swift
// ❌ Error: value has no count method
func countElements<T>(value: T) -> Int { value.count }

// ✅ Works: T: Collection guarantees count exists
func countElements<T: Collection>(value: T) -> Int { value.count }

Hata açıktır: genel herhangi bir tür olabilir ve derleyici count'a sahip olup olmadığını bilmez. Collection kısıtlaması sorunu çözer. Equatable, Hashable, Numeric için de aynı şekilde — genel parametrede yöntem veya işlev çağırmayı planlıyorsanız her zaman protokolü belirtin.

Sıkça Sorulan Sorular

Basitçe ifade etmek gerekirse Swift'te Generic nedir?

Generic, Int, String ve diğer türler için aynı mantığı kopyalamadan her türle çalışan kod yazmanın bir yoludur. Somut bir tür yerine, kullanım noktasında gerçek türle değiştirilen bir yer tutucu kullanılır.

Generic, Any'den nasıl farklıdır?

Generic, derleme zamanında somut tür hakkındaki bilgileri korur, derleyicinin türleri denetlemesine ve optimize edilmiş kod üretmesine olanak tanır. Any, tür silmedir: herhangi bir değer iletilebilir, ancak tür kaybolur ve dönüştürme (as?) gerekir.

Bir protokolle Generic nasıl kısıtlanır?

Açılı parantezler içinde T: SomeProtocol sözdizimini veya ayrı bir where cümlesi where T: SomeProtocol kullanın. Kısıtlamalar, genel parametrenin belirli yöntemleri ve özellikleri desteklemesini sağlar.

Bir protokolde Associated Type nedir?

Associated Type (associatedtype), bir protokol içindeki bir tür için yer tutucudur. Protokol somut bir tür belirtmez, bunun yerine bir associatedtype bildirir ve bu, uygulamada somutlaştırılır: Array'in Element'i, Dictionary'in Key ve Value'su vardır.

Generics somut türlerden daha hızlı mı yoksa daha yavaş mı?

Swift, genel kodu her somut tür için özelleştirilmiş sürümlerde derler. Pratikte, Int için bir genel işlev, Int için elle yazılmış bir işlevden daha yavaş değildir. Soyutlama ek yükü yoktur.

Özet

  • Generic — tür parametresi ile genel programlama mekanizması
  • İşlevler ve türler genel parametrelerle birden çok yinelenen uygulamayı değiştirir
  • where kısıtlamaları genel türlerin kapsamını gerekli koşullarla sınırlar
  • Associated Types protokollerin bildirimde somutlaştırma olmadan genel olmasını sağlar
  • Uzantılar where ile yalnızca koşullar karşılandığında işlevsellik ekler
  • Derleyici özelleştirilmiş kod üretir — generics ek yük eklemez
  • Aşırı parametrelendirme bir anti-kalıptır — generics'i yalnızca tür gerçekten değiştiğinde kullanın

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun