Generic — umumiy turlarning mohiyati va T parametri

Muallif: IT Sectr Nashr etilgan: 2026-06-18 O'qish vaqti: 10 daq

Generic (umumiy dasturlash) — bu Swift mexanizmi bo'lib, turlar va funksiyalarni parametrlashgan tur bilan yozish imkonini beradi. Int, String va maxsus strukturalar uchun kodni takrorlash o'rniga, dasturchi har qanday tur bilan ishlaydigan, ammo qat'iy tiplashtirishni saqlaydigan umumiy yechim yaratadi. Kompilyator foydalanish vaqtida aniq turni almashtiradi, bu esa ishlashni yo'qotmasdan xavfsizlikni kafolatlaydi. Swift Book, 2025 ma'lumotlariga ko'ra, generic parametrlar tilning standart kutubxonasi va SwiftUI asosida yotadigan asosiy imkoniyatlaridan biridir.

Asosiy fikrlar

  • Generic — tur-parametrlari bilan umumiy dasturlash mexanizmi
  • Funksiyalar generic parametrlar bilan kodni takrorlamasdan istalgan tur bilan ishlaydi
  • Where cheklovlari generic qo'llanishini shartlarga javob beradigan turlarga toraytiradi
  • Associated Types protokollarda protokollarning umumiy bo'lishiga imkon beradi
  • Kompilyator har bir aniq tur uchun ixtisoslashtirilgan kod yaratadi

Swiftda Generic nima?

Generic (umumiy tur) — bu turga qarab parametrlash bilan moslashuvchan, qayta foydalaniladigan kod yozish imkonini beradigan Swift sintaktik konstruksiyasidir. Aniq tur o'rniga burchakli qavslarda placeholder yoziladi — odatda , lekin istalgan nomdan foydalanish mumkin. Generic SwiftUI (View, some View), standart kutubxona (Array, Optional) va Combine asosida yotadi.

Generic nima uchun kerak

Genericsiz har bir tur uchun alohida funksiyalar yozish kerak bo'ladi: swapInts, swapStrings, swapDates. Generic swap funksiyasi uchala variantni bitta deklaratsiya bilan almashtiradi. Bu takrorlanishni kamaytiradi, o'qishni osonlashtiradi va kodni nusxalashda xatolik ehtimolini pasaytiradi.

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 kompilyatori genericning har bir aniq qo'llanilishi uchun ixtisoslashtirilgan kod yaratadi. Bu swapValues generic funksiyasining Int uchun qo'lda yozilgan funksiyaga nisbatan qo'shimcha yuklamasi yo'qligini anglatadi. Swift Java kabi tur o'chirishdan foydalanmaydi — generic kompilyatsiya bosqichida ham, ish vaqtida ham mavjud (optimallashtirish ularni ixtisoslashtirishi mumkin bo'lsa ham).

T parametri bilan umumiy funksiyalar

Generic funksiyalar — bir yoki bir nechta tur-parametrlarni qabul qiladigan funksiyalardir. Tur-parametrlar funksiya nomidan keyin burchakli qavslarda ko'rsatiladi: . Ular imzoda ishlatilishi mumkin: argument turi, qaytariladigan tur va funksiya tanasi ichida.

Bir nechta tur-parametrlar

Funksiyada bir nechta generic parametr bo'lishi mumkin. Masalan, findKey funksiyasi K kalitlari va V qiymatlari bo'lgan lug'atni qabul qiladi. Har bir tur-parametr noyobdir va cheklovlarda ishlatilishi mumkin.

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 va where V: Equatable cheklovlari findKey faqat kalitlari xeshlanadigan va qiymatlari taqqoslanadigan lug'at bilan chaqirilishini kafolatlaydi. Bunday cheklovlar byurokratiya emas, balki zaruratdir: Hashablesiz kalit bo'yicha qidiruvni indekslash mumkin emas, Equatablesiz value ni dictValue bilan taqqoslab bo'lmaydi.

Where orqali tur cheklovlari

where — bu generic parametrlarga qo'shimcha cheklovlar qo'yadigan Swift kalit so'zidir. Burchakli qavslarda protokolni oddiy ko'rsatishdan () farqli o'laroq, where murakkabroq shartlarni ifodalash imkonini beradi: bir nechta protokollarga muvofiqlik, tur-parametrlar orasidagi bog'liqlik va associated types aniqlashtirish.

Where sintaksisi

Where bandi funksiya yoki turning imzosidan keyin, ochiluvchi figurali qavsdan oldin yoziladi. Where da T: Comparable & Hashable (bir vaqtning o'zida ikkita protokol) yoki T.U == Int (associated type konkretlashtirish) ko'rsatilishi mumkin.

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 bilan kengaytma faqat shartni qondiradigan turlar uchun metodlar qo'shadi. Container isSorted metodini oladi, Container esa olmaydi, chunki Any Comparable emas. Bu shartli funksionallikning kuchli mexanizmidir.

Protokollarda Associated Types

Associated Types (bog'langan turlar) — bu e'lon qilish bosqichida aniq turni ko'rsatmasdan protokolni umumiy qilish usulidir. o'rniga protokol associatedtype e'lon qiladi, u amalga oshirishda konkretlashtiriladi. Bu ayniqsa kolleksiyalar uchun muhim: Sequence protokoli ketma-ketlik qanday elementlarni o'z ichiga olishini bilmaydi.

Associated types ni where orqali bog'lash

Where yordamida turli protokollarning associated types o'rtasida bog'lanishlar o'rnatilishi mumkin. Masalan, bir protokolning Item i boshqasining Iterator.Element i bilan mos kelishi talab qilinishi mumkin. Bu kompilyatsiya darajasida turlarning mosligini kafolatlaydi.

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 yordamida Element ni Int sifatida konkretlashtiradi. Kompilyator protokolning barcha talablari ushbu tur bilan bajarilishini tekshiradi. Associated types bo'lmasa, generic protokol bilan StackProtocol yozish kerak bo'lardi, lekin Swift Objective-C ko'prigi bilan birlik va yaxshi o'qish uchun associated types dan foydalanadi.

Generic kengaytmalar va subskriptlarda

Generic kengaytmalar qo'shimcha cheklovlar bilan generic turga metodlar qo'shish imkonini beradi. Bu “shartli muvofiqlik” naqshidir, bunda tur faqat ma'lum shartlarda funksionallik oladi. Subskriptlar ham generic bo'lishi mumkin.

Generic subskript

Subskript umumiy bo'lishi mumkin: burchakli qavslarda generic parametrlarni qabul qiladi. Bu indeks har xil turlarda bo'lishi mumkin bo'lgan ixtiyoriy indeksli kolleksiyalarga xavfsiz kirish uchun foydalidir.

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] }
    }
}

Bunday konstruksiya kuchli kompozitsiya beradi: sum metodi faqat sonli massivlarda paydo bo'ladi, ixtiyoriy indekslar bilan subskript esa har qanday butun son indekslar ketma-ketligi bilan ishlaydi. Kompilyatorning o'zi where shartlariga asoslanib, bu a'zolarning ko'rinishini boshqaradi.

Generiklar bilan ishlashda tipik xatolar

Xatolar generic dan foydalanishda ko'pincha noto'g'ri cheklovlar yoki aniq tur kerak bo'lgan joyda generic ishlatish urinishi bilan bog'liq. Dasturchilar duch keladigan uchta keng tarqalgan stsenariyni ko'rib chiqaylik.

Haddan tashqari parametrlash

Aniq tur yetarli bo'lgan joyda generic parametrlar qo'shish — anti-naqshdir. Agar funksiya har doim String bilan ishlasa, uni qilish shart emas. Bu foyda keltirmasdan kodni murakkablashtiradi. Generic faqat tur haqiqatan o'zgarganda oqlanadi, mavhum “kelajak uchun moslashuvchanlik” uchun emas.

Where cheklovining yo'qligi

Metod mavjudligini ko'rsatmasdan generic parametrda metodni chaqirish — xato. agar T: Collection ekanligi ko'rsatilmagan bo'lsa, .count ni chaqira olmaydi. Har doim tur-parametrlarga cheklovlar qo'shing, aks holda kompilyator kodni rad etadi.

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 }

Xato tushunarli: generic har qanday tur bo'lishi mumkin va kompilyator unda count borligini bilmaydi. Collection cheklovi muammoni hal qiladi. Xuddi shunday Equatable, Hashable, Numeric uchun — generic parametrda metodlar yoki operatorlarni chaqirishni rejalashtirsangiz, har doim protokolni ko'rsating.

Tez-tez beriladigan savollar

Swiftda Generic oddiy so'zlar bilan nima?

Generic — bu Int, String va boshqa turlar uchun bir xil mantiqni takrorlamasdan istalgan tur bilan ishlaydigan kod yozish usulidir. Aniq tur o'rniga foydalanish vaqtida haqiqiy tur bilan almashtiriladigan placeholder ishlatiladi.

Generic Any dan qanday farq qiladi?

Generic kompilyatsiya bosqichida aniq tur haqidagi ma'lumotni saqlaydi, bu kompilyatorga turlarni tekshirish va optimallashtirilgan kod yaratish imkonini beradi. Any — bu turni o'chirish: istalgan qiymat uzatilishi mumkin, ammo tur yo'qoladi va konvertatsiya (as?) talab qilinadi.

Generic ni protokol bilan qanday cheklash mumkin?

Burchakli qavslarda T: SomeProtocol sintaksisidan yoki alohida where T: SomeProtocol bandidan foydalaning. Cheklovlar generic parametrning ma'lum metodlar va xususiyatlarni qo'llab-quvvatlashini kafolatlaydi.

Protokolda Associated Type nima?

Associated Type (associatedtype) — protokol ichidagi tur uchun placeholderdir. Protokol aniq turni ko'rsatmaydi, balki associatedtype e'lon qiladi, u amalga oshirishda konkretlashtiriladi: Array Element ga, Dictionary Key va Value ga ega.

Generic aniq turlardan tezroqmi yoki sekinroqmi ishlaydi?

Swift generic kodni har bir aniq tur uchun ixtisoslashtirilgan versiyalarga kompilyatsiya qiladi. Amalda, Int uchun generic funksiya Int uchun qo'lda yozilgan funksiyadan sekin emas. Abstraksiya uchun qo'shimcha yuklama yo'q.

Xulosa

  • Generic — tur-parametr bilan umumiy dasturlash mexanizmi
  • Funksiyalar va turlar generic parametrlar bilan ko'plab takrorlanadigan implementatsiyalarni almashtiradi
  • Where cheklovlari generic qo'llanishini zaruriy shartlargacha toraytiradi
  • Associated Types protokollarga e'lon qilish bosqichida konkretlashtirmasdan umumiy bo'lishga imkon beradi
  • Kengaytmalar where bilan faqat shartlar bajarilganda funksionallik qo'shadi
  • Kompilyator ixtisoslashtirilgan kod yaratadi — generic qo'shimcha yuklama qo'shmaydi
  • Haddan tashqari parametrlash — anti-naqsh, generic ni faqat tur haqiqatan o'zgarganda ishlating

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing