- Published on
Swiftda some va any — Opaque va Existential Types
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
SwiftUI da 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 — 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
| Xususiyat | some | any |
|---|---|---|
| Tur aniqligi | Compile-time (tez) | Runtime (sekin) |
| Turli turlar | ❌ Faqat bitta tur | ✅ Turli turlar |
| Massivda | Bir xil turlar | Aralash turlar |
| SwiftUI body | ✅ Standart | ⚠️ Kerak emas |
| Saqlash | Stack (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.