Generic — ümumi tiplərin mahiyyəti və T parametri

Müəllif: IT Sectr Dərc olunub: 2026-06-18 Oxuma vaxtı: 10 dəq

Generic (ümumi proqramlaşdırma) — bu, Swift mexanizmidir, tipləri və funksiyaları parametrləşdirilmiş tip ilə yazmağa imkan verir. Int, String və xüsusi strukturlar üçün kodu təkrarlamaq əvəzinə, tərtibatçı istənilən tiplə işləyən, eyni zamanda sərt tipizasiyanı qoruyan ümumi bir həll yaradır. Kompilyator istifadə zamanı konkret tipi əvəz edir ki, bu da performans itkisi olmadan təhlükəsizliyi təmin edir. Swift Book, 2025-ə görə, generic parametrlər dilin əsas standart kitabxanasının və SwiftUI-nin təməlində duran əsas imkanlarından biridir.

Əsas məqamlar

  • Generic — tip-parametrləri olan ümumi proqramlaşdırma mexanizmi
  • Funksiyalar generic parametrlərlə kodu təkrarlamadan istənilən tiplə işləyir
  • Where məhdudiyyətləri generic-in tətbiqini şərtlərə cavab verən tiplərə qədər daraldır
  • Associated Types protokollarda protokolların ümumi olmasına imkan verir
  • Kompilyator hər konkret tip üçün ixtisaslaşdırılmış kod yaradır

Swift-də Generic nədir?

Generic (ümumi tip) — bu, tipə görə parametrləşdirmə ilə çevik, təkrar istifadə oluna bilən kod yazmağa imkan verən Swift sintaktik konstruksiyasıdır. Konkret tip əvəzinə bucaqlı mötərizələrdə placeholder yazılır — adətən , lakin istənilən ad istifadə oluna bilər. Generic SwiftUI (View, some View), standart kitabxana (Array, Optional) və Combine-in təməlində durur.

Generic nə üçün lazımdır

Generic olmadan hər tip üçün ayrı funksiyalar yazmaq lazım gələrdi: swapInts, swapStrings, swapDates. Generic swap funksiyası hər üç variantı bir bəyannamə ilə əvəz edir. Bu, təkrarlanmanı azaldır, oxunaqlılığı artırır və kodu kopyalayarkən səhv ehtimalını azaldı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 kompilyatoru generic-in hər konkret istifadəsi üçün ixtisaslaşdırılmış kod yaradır. Bu o deməkdir ki, swapValues generic funksiyasının Int üçün əl ilə yazılmış funksiya ilə müqayisədə əlavə yükü yoxdur. Swift Java kimi tip silinməsindən istifadə etmir — generic həm kompilyasiya mərhələsində, həm də icra zamanı mövcuddur (optimallaşdırma onları ixtisaslaşdıra bilsə də).

T parametri ilə ümumi funksiyalar

Generic funksiyalar — bir və ya daha çox tip-parametr qəbul edən funksiyalardır. Tip-parametrlər funksiya adından sonra bucaqlı mötərizələrdə göstərilir: . Onlar imzada istifadə oluna bilər: arqument tipi, qaytarılan tip və funksiya gövdəsi daxilində.

Çoxsaylı tip-parametrlər

Funksiyanın bir neçə generic parametri ola bilər. Məsələn, findKey funksiyası K açarları və V dəyərləri olan lüğət qəbul edir. Hər tip-parametr unikaldır və məhdudiyyətlərdə istifadə oluna bilər.

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 və where V: Equatable məhdudiyyətləri findKey-in yalnız açarları heşlənə bilən və dəyərləri müqayisə oluna bilən lüğətlə çağrılmasını təmin edir. Bu cür məhdudiyyətlər bürokratiya deyil, zərurətdir: Hashable olmadan açar üzrə axtarışı indeksləşdirmək mümkün deyil, Equatable olmadan value-ni dictValue ilə müqayisə etmək mümkün deyil.

Where ilə tip məhdudiyyətləri

where — bu, generic parametrlərə əlavə məhdudiyyətlər qoyan Swift açar sözüdür. Bucaqlı mötərizələrdə protokolun sadə göstərilməsindən () fərqli olaraq, where daha mürəkkəb şərtləri ifadə etməyə imkan verir: bir neçə protokola uyğunluq, tip-parametrlər arasında əlaqə və associated types-in dəqiqləşdirilməsi.

Where sintaksisi

Where bəndi funksiya və ya tipin imzasından sonra, açılan qıvrım mötərizədən əvvəl yazılır. Where-də T: Comparable & Hashable (eyni anda iki protokol) və ya T.U == Int (associated type-ın konkretləşdirilməsi) göstərilə bilər.

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 ilə genişləndirmə yalnız şərti ödəyən tiplər üçün metodlar əlavə edir. Container isSorted metodunu alır, Container isə almır, çünki Any Comparable deyil. Bu, şərti funksionallığın güclü mexanizmidir.

Protokollarda Associated Types

Associated Types (əlaqəli tiplər) — bu, bəyannamə mərhələsində konkret tipi göstərmədən protokolu ümumi etmək üsuludur. əvəzinə protokol associatedtype elan edir, o isə tətbiqdə konkretləşdirilir. Bu, xüsusilə kolleksiyalar üçün vacibdir: Sequence protokolu ardıcıllığın hansı elementləri ehtiva edəcəyini bilmir.

Associated types-in where vasitəsilə əlaqələndirilməsi

Where vasitəsilə müxtəlif protokolların associated types arasında əlaqələr qurula bilər. Məsələn, bir protokolun Item-inin digərinin Iterator.Element-i ilə uyğun olması tələb edilə bilər. Bu, kompilyasiya səviyyəsində tiplərin uyğunluğunu təmin edir.

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 istifadə edərək Element-i Int olaraq konkretləşdirir. Kompilyator protokolun bütün tələblərinin bu tiplə yerinə yetirildiyini yoxlayır. Associated types olmadan generic protokol ilə StackProtocol yazmaq lazım gələrdi, lakin Swift Objective-C körpüləri ilə vahidlik və daha yaxşı oxunaqlılıq üçün associated types istifadə edir.

Generic genişləndirmələrdə və subskriptlərdə

Generic genişləndirmələr əlavə məhdudiyyətlərlə generic tipə metodlar əlavə etməyə imkan verir. Bu, tipin funksionallığı yalnız müəyyən şərtlər altında aldığı “şərti uyğunluq” (conditional conformance) nümunəsidir. Subskriptlər də generic ola bilər.

Generic subskript

Subskript ümumi ola bilər: bucaqlı mötərizələrdə generic parametrlər qəbul edir. Bu, indeksin müxtəlif tiplərdən ola biləcəyi ixtiyari indeksli kolleksiyalara təhlükəsiz giriş üçün faydalı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] }
    }
}

Belə konstruksiya güclü kompozisiya verir: sum metodu yalnız ədədi massivlərdə görünür, ixtiyari indekslərlə subskript isə istənilən tam indeks ardıcıllığı ilə işləyir. Kompilyator where şərtləri əsasında bu üzvlərin görünməsini özü idarə edir.

Generiklərlə işləyərkən tipik səhvlər

Səhvlər generic istifadə edərkən çox vaxt yanlış məhdudiyyətlər və ya konkret tipin lazım olduğu yerdə generic istifadə etmək cəhdi ilə bağlıdır. Tərtibatçıların qarşılaşdığı üç ümumi ssenariyə baxaq.

Həddindən artıq parametrləşdirmə

Konkret tipin kifayət etdiyi yerdə generic parametrlər əlavə etmək — anti-nümunədir. Əgər funksiya həmişə String ilə işləyirsə, onu etmək lazım deyil. Bu, fayda vermədən kodu çətinləşdirir. Generic yalnız tip həqiqətən dəyişdikdə əsaslandırılır, abstrakt “gələcək üçün çeviklik” üçün deyil.

Where məhdudiyyətinin olmaması

Metodun mövcud olduğunu göstərmədən generic parametr üzərində metodu çağırmaq — səhvdir. T: Collection olduğu göstərilməyibsə, .count çağıra bilməz. Həmişə tip-parametrlərə məhdudiyyətlər əlavə edin, əks halda kompilyator kodu rədd edəcək.

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 }

Səhv aydındır: generic istənilən tip ola bilər və kompilyator onun count-a sahib olduğunu bilmir. Collection məhdudiyyəti problemi həll edir. Eynilə Equatable, Hashable, Numeric üçün — generic parametr üzərində metodları və ya operatorları çağırmağı planlaşdırırsınızsa, həmişə protokolu göstərin.

Tez-tez verilən suallar

Swift-də Generic sadə sözlərlə nədir?

Generic — bu, Int, String və digər tiplər üçün eyni məntiqi təkrarlamadan istənilən tiplə işləyən kod yazmaq üsuludur. Konkret tip əvəzinə istifadə zamanı real tiplə əvəz olunan placeholder istifadə olunur.

Generic Any-dən nə ilə fərqlənir?

Generic kompilyasiya mərhələsində konkret tip haqqında məlumatı saxlayır ki, bu da kompilyatora tipləri yoxlamağa və optimallaşdırılmış kod yaratmağa imkan verir. Any — tip silməsidir: istənilən dəyər ötürülə bilər, lakin tip itir və çevirmə (as?) tələb olunur.

Generic-i protokolla necə məhdudlaşdırmaq olar?

Bucaqlı mötərizələrdə T: SomeProtocol sintaksisindən və ya ayrıca where T: SomeProtocol bəndindən istifadə edin. Məhdudiyyətlər generic parametrin müəyyən metodları və xassələri dəstəkləməsini təmin edir.

Protokolda Associated Type nədir?

Associated Type (associatedtype) — protokol daxilində tip üçün placeholderdir. Protokol konkret tipi göstərmir, associatedtype elan edir, o isə tətbiqdə konkretləşdirilir: Array-də Element, Dictionary-də Key və Value.

Generic konkret tiplərdən daha sürətli və ya yavaş işləyir?

Swift generic kodu hər konkret tip üçün ixtisaslaşdırılmış versiyalara kompilyasiya edir. Praktikada Int üçün generic funksiya Int üçün əl ilə yazılmış funksiyadan yavaş deyil. Abstraksiyaya görə əlavə yük yoxdur.

Nəticə

  • Generic — tip-parametr ilə ümumi proqramlaşdırma mexanizmi
  • Funksiyalar və tiplər generic parametrlərlə çoxsaylı təkrarlanan tətbiqləri əvəz edir
  • Where məhdudiyyətləri generic-in tətbiqini zəruri şərtlərə qədər daraldır
  • Associated Types protokollara bəyannamə mərhələsində konkretləşdirmədən ümumi olmağa imkan verir
  • Genişləndirmələr where ilə yalnız şərtlər yerinə yetirildikdə funksionallıq əlavə edir
  • Kompilyator ixtisaslaşdırılmış kod yaradır — generic əlavə yük əlavə etmir
  • Həddindən artıq parametrləşdirmə — anti-nümunə, generic-i yalnız tip həqiqətən dəyişdikdə istifadə edin

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun