Opaque Type (qeyri-şəffaf tip) — Swift mexanizmidir ki, funksiyaya müəyyən tipin dəyərini qaytarmağa imkan verir, konkret tipi çağıran koda açıqlamadan. Qaytarılan tipdə açar söz some — ən məşhur nümunə: some View SwiftUI-də “View-ə uyğun hansısa tip qaytarılır, amma hansı dəqiq — tətbiq detalıdır” mənasını verir. Opaque type tipin kimliyini qoruyur (protokolun tip kimi olmasından fərqli olaraq), bu da kompilyatora kodu optimallaşdırmağa və qaytarılan tipin ardıcıllığını təmin etməyə imkan verir. Swift Book, 2025-ə görə, opaque types associated types olan protokollar problemini həll edir, belə protokolların dəyərlərini funksiyalardan qaytarmağa imkan verir.
Əsas məqamlar
Opaque Type — some açar sözü ilə elan edilmiş, konkret implementasiyanı çağıran koddan gizlədən qaytarılan tipdir. Çağıran tərəf yalnız qaytarılan dəyərin müəyyən protokola uyğun olduğunu bilir, amma some arxasında hansı dəqiq tipin dayandığını bilmir. Eyni zamanda kompilyator dəqiq tipi bilir və onu statik dispetçerizasiya və optimallaşdırma üçün istifadə edir.
Swift 5.1-də (SE-0244) opaque types-in yaranmasından əvvəl associated types olan protokolu funksiyadan boxing-sarğısı olmadan qaytarmaq mümkün deyildi. Məsələn, Equatable protokolunun associated type-ı var və funksiya sadəcə Equatable qaytara bilmirdi — kompilyator “protocol can only be used as a generic constraint” xətası verirdi. Opaque type bu problemi həll etdi.
func makeInt() -> some Equatable {
return 42
}
func makeString() -> some Equatable {
return "Hello"
}
// Kompilyator bilir ki, makeInt Int qaytarır
// makeInt() == makeString() — ❌ xəta, fərqli tiplər
Hər iki funksiya some Equatable qaytarır, lakin konkret tiplər fərqlidir: Int və String. Onları == vasitəsilə müqayisə etmək cəhdi kompilasiya xətasına səbəb olacaq, çünki opaque type zəmanət verir ki, konkret çağırışdan eyni tip qaytarılır, amma müxtəlif funksiyalar arasında deyil. Bu — xüsusiyyətdir, səhv deyil: opaque type tipin kimliyini qoruyur, protokolun tip kimi (any Equatable) onu itirdiyi yerdə.
Generic və Opaque Type — eyni sikkənin iki üzü. Generic çağıran koda tipi seçməyə imkan verir, opaque type isə funksiyaya tipi çağıran koddan gizlətməyə imkan verir. Fərq nəzarət istiqamətindədir.
| Xüsusiyyət | Generic | Opaque some |
|---|---|---|
| Tipi kim seçir | Çağıran kod | Funksiya/metod |
| Tip kimliyi | Qorunur (stabil) | Qorunur (stabil) |
| Return budaqlarının sayı | Bir (generic vasitəsilə) | Bütün budaqlarda eyni tip |
| Tətbiq | Alqoritmlər, məlumat strukturları | SwiftUI, fabrik metodları |
Generic funksiyasında caller hansı tipdən istifadə edəcəyinə qərar verir. Funksiya məhdudiyyətlərə cavab verən istənilən T ilə işləməlidir. Opaque type üçün caller konkret tipi bilmir — qərarı implementasiya verir.
// Generic: caller tipi seçir
func identity<T>(_ value: T) -> T { value }
let x: Int = identity(42)
// Opaque: funksiya tipi gizlədir
func makeSomeEquatable() -> some Equatable { 42 }
let y = makeSomeEquatable()
Generic və opaque type arasında seçim niyyətdən asılıdır. Çağıran kod tipi seçməlidirsə — generic istifadə edin. Funksiya implementasiya detallarını gizlətməlidirsə — some istifadə edin. SwiftUI some View seçdi, çünki body daxildə çevik, xaricdə isə sabit olmalıdır.
some — Swift 5.1-də (SE-0244) təqdim edilmiş Swift açar sözüdür. Qaytarılan mövqedə opaque type elan etmək üçün, həmçinin parametrlərdə (SE-0341) və xassələrdə istifadə olunur. some zəmanət verir ki, konkret tip sabitdir və kompilyatora məlumdur, lakin xarici koddan gizlidir.
Swift 5.7-dən başlayaraq some yalnız qaytarılan mövqedə deyil, həm də parametrlərdə istifadə oluna bilər. Parametrdə some Equatable o deməkdir ki, “bu funksiya istənilən Equatable tipini qəbul edir, lakin konkret bədən daxilində bütün çağırışlar eyni tipi görür”.
func areEqual(_ a: some Equatable, _ b: some Equatable) -> Bool {
// a və b — potensial fərqli tiplər, == birbaşa işləməyəcək
return isEqual(a, b)
}
func isEqual<T: Equatable>(_ a: T, _ b: T) -> Bool {
return a == b
}
Parametrlərdə some istifadəsi
any — Swift 5.6+-da ekzistensial tipləri (protokol tip kimi) açıq elan etmək üçün açar sözdür. Some-dən fərqli olaraq, any tipin kimliyini silir: kompilyator protokol arxasında hansı konkret tipin dayandığını bilmir. Bu çeviklik verir (bir massivdə müxtəlif tipləri saxlamaq olar), lakin performans hesabına.
some — statik polimorfizm: kompilyator konkret tipi bilir, birbaşa dispetçerizasiyadan istifadə edir və kodu inline edə bilər. any — dinamik polimorfizm: virtual metodlar cədvəli (existential container) istifadə olunur, bu da dolayılıq əlavə edir.
protocol Drawable {
func draw()
}
// some: statik tip məlumdur
func makeDrawable() -> some Drawable {
return Circle() // Tək qaytarılan tip
}
// any: dinamik, müxtəlif tipləri saxlaya bilər
var shapes: [any Drawable] = [Circle(), Square()]
shapes.append(Triangle())
Some və any arasında seçim performans və çeviklik arasında kompromisdir. Some daha sürətlidir, lakin bir implementasiya ilə məhdudlaşdırır. Any daha çevikdir (tipləri qarışdırmaq olar), lakin dinamik dispetçerizasiya səbəbindən daha yavaşdır. SwiftUI-də body üçün həmişə some View istifadə olunur, çünki hər View-in body-si bir konkret tipdir.
Opaque Type Swift-in fundamental problemini həll edir: associated types (PAT) olan protokollar birbaşa tip kimi istifadə edilə bilməz. Funksiya sadəcə Collection qaytara bilməz — kompilyator Element-in təyin edilməsini tələb edir. some Collection bunu həll edir, associated type-ı gizlətməklə.
Opaque type olmadan Collection qaytarmaq üçün konkret tipdən (Array
func makeReversedCollection<T>(
of array: [T]
) -> some Collection {
return array.reversed()
}
let result = makeReversedCollection(of: [1, 2, 3])
// result — ReversedCollection>, hidden from caller
for item in result {
print(item)
}
result üzərində iterasiya etmək olar, lakin birbaşa ReversedCollection xassələrinə müraciət etmək olmaz. Bu inkapsulyasiyanı qoruyur: əgər sonradan reversed() başqa metodla əvəz edilərsə, çağıran kod sınmaz. Opaque type API-ni dəyişmədən implementasiyanı dəyişmək azadlığı verir.
some View — opaque type-in ən məşhur tətbiqidir. SwiftUI-də hər View body-ni some View kimi elan edir. Bu o deməkdir ki, body hansısa konkret View tipini qaytarır, lakin proqramçı bunun nə olduğunu düşünməməlidir — TupleView, Group, ModifiedContent və ya framework-dən hər hansı digər tip.
Opaque type olmadan body konkret tip qaytarmalı olardı, məsələn, ModifiedContent<Button<Text>, Padding>, bu praktiki deyil. some View bu mürəkkəbliyi gizlədir. Kompilyator body-nin dəqiq tipini kompilasiya zamanı avtomatik çıxarır.
struct ContentView: View {
var body: some View {
VStack {
Text("Salam")
.font(.title)
Button("Mənə toxun") {
print("Toxunuldu")
}
}
.padding()
}
}
Kompilyator body-ni ModifiedContent<VStack<TupleView<(Text, Button<Text>)>>, Padding> kimi çıxarır. Proqramçı some View görür. Layout VStack-dən HStack-ə dəyişdirilərsə, kompilyator avtomatik tipi yenidən çıxarır — heç bir əl düzəlişi tələb olunmur. Opaque type-in sehri budur: proqramçı interfeysin məntiqinə fokuslanır, kompozisiya tiplərinə deyil.
Tez-tez verilən suallar
Opaque Type — some açar sözü ilə elan edilmiş, konkret implementasiyanı çağıran koddan gizlədən tipdir. Kompilyator dəqiq tipi bilir, lakin funksiyadan istifadə edən proqramçı yalnız protokolu görür.
some — statik kimliyə malik opaque type: kompilyator konkret tipi bilir. any — dinamik dispetçerizasiyalı ekzistensial tip: tip kimliyi silinib. Some daha məhsuldardır, any daha çevikdir.
some View kompilyatorun avtomatik çıxardığı mürəkkəb konkret body tipini gizlədir. Bu, proqramçını Generic-sarğılardan (VStack, Group, ModifiedContent) ibarət dəqiq tipi yazmaq zərurətindən azad edir.
Bəli, Swift 5.7-dən etibarən. Parametrlərdə some generic parametr üzərində sintaktik şəkərdir. Funksiya elanlarını sadələşdirir, xüsusilə protokollarla işləyərkən, burada hər some-parametr ayrıca
Kompilyator xəta verəcək: opaque type bütün return budaqlarının eyni konkret tipi qaytarmasını tələb edir. Bu, tip kimliyini qorumaq üçün bilərəkdən edilib. Müxtəlif tiplər qaytarmaq lazımdırsa, any istifadə edin.
Nəticə
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.
Həm də oxuyun