Published on

Swiftda some va any — Opaque va Existential Types

Authors

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

some — opaque 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.

any — existential 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 — SwiftUIda 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!
// }


// ═══════════════════════════════════════
//  SWIFTUIDA 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