Published on

Swiftda some va any — Opaque va Existential Types

Authors

SwiftUI da var body: some View deb yozamiz. Lekin some nima? any dan qanday farqi bor?

someopaque type. "Bitta aniq tur qaytaraman, lekin qaysi ekanini tashqariga aytmayman" degan ma'no. Compiler aniq turni biladi va optimizatsiya qiladi. Funksiya har doim bir xil turdagi qiymat qaytarishi kerak.

anyexistential type. "Istalgan tur bo'lishi mumkin" degan ma'no. Runtime da aniqlanadi, sekinroq, lekin moslashuvchan. Massivda turli turlardagi ob'ektlarni saqlash uchun kerak.

some — Opaque Type

some ishlatganda funksiya har doim bitta aniq turni qaytaradi. Compiler bu turni biladi va inline, devirtualize kabi optimizatsiyalar qiladi. some View — SwiftUI da body har doim bitta aniq View turi qaytaradi (masalan, VStack<TupleView<...>>).

// ═══════════════════════════════════════
//  SOME — "bitta aniq tur, lekin yashiraman"
// ═══════════════════════════════════════

protocol Shakl {
    func chiz() -> String
}

struct Doira: Shakl {
    func chiz() -> String { "⭕ Doira" }
}

struct Kvadrat: Shakl {
    func chiz() -> String { "⬜ Kvadrat" }
}

// some Shakl — bitta ANIQ tur qaytaradi
// Compiler biladi bu Doira — lekin chaqiruvchi faqat Shakl ni ko'radi
func yaratShaklni() -> some Shakl {
    return Doira()  // ✅ Har doim Doira qaytaradi
}

// ❌ XATO — turli turlar qaytarib bo'lmaydi!
// func xatoFunksiya(shart: Bool) -> some Shakl {
//     if shart { return Doira() }
//     else { return Kvadrat() }  // ❌ Ikki turli tur!
// }


// ═══════════════════════════════════════
//  SWIFTUI DA SOME VIEW
// ═══════════════════════════════════════
// var body: some View {
//     // Bu yerda HAR DOIM bitta aniq View turi qaytadi
//     // Compiler: bu ModifiedContent<Text, _PaddingLayout> turini biladi
//     Text("Salom").padding()
// }

any — Existential Type

any — turli turlardagi ob'ektlarni bitta o'zgaruvchida saqlash imkoni. Funksiya turli turlarni qaytarishi mumkin. Massivda aralash turlar saqlash mumkin: [any Shakl]. Lekin any sekinroq — runtime da tur aniqlanadi va heap da saqlanadi.

// ═══════════════════════════════════════
//  ANY — "istalgan tur bo'lishi mumkin"
// ═══════════════════════════════════════

// any Shakl — istalgan Shakl turini saqlaydi
// Runtime da aniqlanadi — sekinroq lekin moslashuvchan
func yasaTasodifiy() -> any Shakl {
    if Bool.random() {
        return Doira()    // ✅ Doira
    } else {
        return Kvadrat()  // ✅ Kvadrat — turli turlar mumkin!
    }
}


// ═══════════════════════════════════════
//  MASSIVDA TURLI TURLAR
// ═══════════════════════════════════════
// some — massivda FAQAT bitta tur
let faqatDoiralar: [some Shakl] = [Doira(), Doira()]  // ✅ hammasi Doira

// any — massivda TURLI turlar
let aralash: [any Shakl] = [Doira(), Kvadrat(), Doira()]  // ✅ aralash
// Massivda turli turlar bo'lganda any KERAK

some vs any — amaliy farq

Tezlik farqi: some compile-time da aniqlanadi — stack da saqlanadi, tez. any runtime da aniqlanadi — existential container (box) yaratiladi, heap da saqlanadi, sekinroq. SwiftUI body da some View ishlatilishining sababi ham shu — tezlik.

// ═══════════════════════════════════════
//  TEZLIK FARQI
// ═══════════════════════════════════════

// some — compile-time aniqlanadi
// Compiler aniq turni biladi → optimizatsiya qiladi
// Stack da saqlanadi → tez
func tezShaklYarat() -> some Shakl {
    Doira()  // Compiler: "bu Doira" → inline, devirtualize
}

// any — runtime da aniqlanadi
// Compiler turni bilmaydi → existential container (box)
// Heap da saqlanadi → sekinroq
func sekinShaklYarat() -> any Shakl {
    Bool.random() ? Doira() : Kvadrat()
    // Compiler: "nima kelishini bilmayman" → box yaratish
}


// ═══════════════════════════════════════
//  QACHON NIMA ISHLATISH
// ═══════════════════════════════════════

// ✅ some — funksiya har doim BIR TUR qaytarsa
// ✅ some — SwiftUI body, computed property
// ✅ some — tezlik muhim bo'lsa

// ✅ any — massivda TURLI turlar
// ✅ any — funksiya TURLI turlar qaytarsa
// ✅ any — moslashuvchanlik muhim bo'lsa

Primary Associated Type

Swift 5.7 dan boshlab some Collection<Int> kabi yozish mumkin — bu primary associated type. Element turini ko'rsatib, aniq collection turini yashirish. any Collection<Int> ham mumkin — turli collection turlari (Array, Set) aralashtirilishi mumkin.

// ═══════════════════════════════════════
//  SWIFT 5.7+ — some Collection<Int>
// ═══════════════════════════════════════

// Eski usul — aniq tur ko'rsatish kerak
func sonlarniOl() -> [Int] {
    [1, 2, 3, 4, 5]
}

// some bilan — aniq tur yashiringan
// lekin element turi ko'rsatilgan
func sonlarniOlSome() -> some Collection<Int> {
    [1, 2, 3, 4, 5]
    // Array, Set yoki boshqa Collection bo'lishi mumkin
    // Chaqiruvchi faqat "Int elementli Collection" ni biladi
}

// any bilan
func sonlarniOlAny() -> any Collection<Int> {
    if Bool.random() {
        return [1, 2, 3]      // Array
    } else {
        return Set([4, 5, 6]) // Set
    }
}

Qoidalar jadvali

Xususiyatsomeany
Tur aniqligiCompile-time (tez)Runtime (sekin)
Turli turlar❌ Faqat bitta tur✅ Turli turlar
MassivdaBir xil turlarAralash turlar
SwiftUI body✅ Standart⚠️ Kerak emas
SaqlashStack (tez)Heap/box (sekin)

🎯 Topshiriq

Hayvon protokol yarating (ism, tovush() metod). Mushuk va It struct yarating. some Hayvon qaytaradigan funksiya yozing. any Hayvon qaytaradigan funksiya yozing. [any Hayvon] massiv yaratib, forEach bilan tovushlarni chiqaring.

Buy mea coffee