Opaque Type, bir fonksiyonun çağıran koda somut türü açıklamadan bir türün değerini döndürmesine izin veren bir Swift mekanizmasıdır. Dönüş türündeki some anahtar kelimesi en ünlü örnektir: SwiftUI'deki some View, “fonksiyon View'a uygun bir tür döndürür, ancak tam olarak hangisi bir uygulama detayıdır” anlamına gelir. Opaque type, tür kimliğini korur (bir tür olarak protokolün aksine), bu da derleyicinin kodu optimize etmesine ve döndürülen türün tutarlılığını garanti etmesine olanak tanır. Swift Book, 2025'e göre, opaque types ilişkili türlere sahip protokollerin sorununu çözerek, fonksiyonlardan bu tür protokollerin değerlerinin döndürülmesine izin verir.
Önemli Noktalar
Opaque Type, some anahtar kelimesiyle bildirilen ve çağıran koddan somut uygulamayı gizleyen bir dönüş türüdür. Çağıran, döndürülen değerin belirli bir protokole uygun olduğunu bilir, ancak some'un arkasında tam olarak hangi tür olduğunu bilmez. Bu arada derleyici, tam türü bilir ve statik dağıtım ve optimizasyon için kullanır.
Swift 5.1'de (SE-0244) opaque types tanıtılmadan önce, bir boxing sarmalayıcısı olmadan bir fonksiyondan ilişkili türlere sahip bir protokolü döndürmek imkansızdı. Örneğin, Equatable protokolünün ilişkili bir türü vardır ve bir fonksiyon basitçe Equatable döndüremezdi — derleyici “protokol yalnızca genel kısıtlama olarak kullanılabilir” hatası verirdi. Opaque type bu sorunu çözdü.
func makeInt() -> some Equatable {
return 42
}
func makeString() -> some Equatable {
return "Hello"
}
// Derleyici makeInt'in Int döndürdüğünü bilir
// makeInt() == makeString() — ❌ hata, farklı türler
Her iki fonksiyon da some Equatable döndürür, ancak somut türler farklıdır: Int ve String. Bunları == ile karşılaştırmaya çalışmak derleme hatasına neden olur çünkü opaque type, belirli bir çağrının aynı türü döndürdüğünü garanti eder, ancak farklı fonksiyonlar arasında garanti etmez. Bu bir özelliktir, hata değil: opaque type, bir tür olarak protokolün (any Equatable) kaybettiği tür kimliğini korur.
Generic ve Opaque Type aynı madalyonun iki yüzüdür. Generics, çağıran kodun türü seçmesine izin verirken, opaque type fonksiyonun türü çağıran koddan gizlemesine izin verir. Fark, kontrolün yönündedir.
| Özellik | Generic | Opaque some |
|---|---|---|
| Türü kim seçer | Çağıran kod | Fonksiyon/metot |
| Tür kimliği | Korunur (kararlı) | Korunur (kararlı) |
| Dönüş dalı sayısı | Bir (generic ile) | Tüm dallarda aynı tür |
| Kullanım | Algoritmalar, veri yapıları | SwiftUI, fabrika metotları |
Genel bir fonksiyonda, çağıran hangi türün kullanılacağına karar verir. Fonksiyon, kısıtlamaları karşılayan herhangi bir T ile çalışmalıdır. Opaque type için, çağıran somut türü bilmez — uygulama kararı verir.
// Generic: çağıran türü seçer
func identity<T>(_ value: T) -> T { value }
let x: Int = identity(42)
// Opaque: fonksiyon türü gizler
func makeSomeEquatable() -> some Equatable { 42 }
let y = makeSomeEquatable()
Generic ve opaque type arasındaki seçim niyete bağlıdır. Çağıran kod türü seçmeliyse, generics kullanın. Fonksiyon uygulama detaylarını gizlemeliyse, some kullanın. SwiftUI, some View'ı tam da body içte esnek ancak dışta kararlı olması gerektiği için seçti.
some, Swift 5.1'de (SE-0244) tanıtılan bir Swift anahtar kelimesidir. Dönüş pozisyonunda opaque type bildirmek için ve ayrıca parametrelerde (SE-0341) ve özelliklerde kullanılır. some, somut türün kararlı ve derleyici tarafından bilinir ancak dış koddan gizli olduğunu garanti eder.
Swift 5.7'den itibaren some, yalnızca dönüş pozisyonunda değil, parametrelerde de kullanılabilir. Bir parametrede some Equatable, “bu fonksiyon herhangi bir Equatable türünü kabul eder, ancak belirli bir gövde içindeki tüm çağrılar aynı türü görür” anlamına gelir.
func areEqual(_ a: some Equatable, _ b: some Equatable) -> Bool {
// a ve b — potansiyel olarak farklı türler, == doğrudan çalışmaz
return isEqual(a, b)
}
func isEqual<T: Equatable>(_ a: T, _ b: T) -> Bool {
return a == b
}
Parametrelerde some kullanmak,
any, varoluşsal türleri (bir tür olarak protokol) açıkça bildirmek için Swift 5.6+ anahtar kelimesidir. Some'un aksine, any tür kimliğini siler: derleyici, protokolün arkasında hangi somut türün gizlendiğini bilmez. Bu esneklik sağlar (aynı dizide farklı türleri saklayabilirsiniz), ancak performans pahasına.
some — statik polimorfizm: derleyici somut türü bilir, doğrudan dağıtım kullanır ve kodu satıriçi yapabilir. any — dinamik polimorfizm: sanal metot tablosu (varoluşsal konteyner) kullanılır, bu da dolaylılık ekler.
protocol Drawable {
func draw()
}
// some: statik tür bilinir
func makeDrawable() -> some Drawable {
return Circle() // Tek dönüş türü
}
// any: dinamik, farklı türler saklayabilir
var shapes: [any Drawable] = [Circle(), Square()]
shapes.append(Triangle())
some ve any arasındaki seçim, performans ve esneklik arasında bir ödünleşmedir. Some daha hızlıdır ancak tek bir uygulamayla sınırlıdır. Any daha esnektir (türleri karıştırabilirsiniz) ancak dinamik dağıtım nedeniyle daha yavaştır. SwiftUI'de, body her zaman some View kullanır çünkü her View'ın body'si tek bir somut türdür.
Opaque Type, Swift'in temel bir sorununu çözer: ilişkili türlere sahip protokoller (PAT) doğrudan bir tür olarak kullanılamaz. Bir fonksiyon basitçe Collection döndüremez — derleyici Element belirtilmesini ister. some Collection, ilişkili türü gizleyerek bunu çözer.
Opaque type olmadan, bir Collection döndürmek için somut bir tür (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 üzerinde yineleme yapılabilir, ancak ReversedCollection'ın özelliklerine doğrudan erişemezsiniz. Bu, kapsüllemeyi korur: daha sonra reversed() işlevini farklı bir uygulamaya sahip başka bir metotla değiştirirseniz, çağıran kod bozulmaz. Opaque type, API'yi değiştirmeden uygulamayı değiştirme özgürlüğü verir.
some View, opaque type'ın en ünlü kullanımıdır. SwiftUI'deki her View, body'yi some View olarak bildirir. Bu, body'nin somut bir View türü döndürdüğü anlamına gelir, ancak geliştiricinin tam olarak ne olduğunu düşünmesi gerekmez — TupleView, Group, ModifiedContent veya framework'teki başka bir tür.
Opaque type olmadan, body somut bir tür döndürmek zorunda kalırdı, örneğin ModifiedContent<Button<Text>, Padding>, ki bu pratik değildir. some View bu karmaşıklığı gizler. Derleyici, derleme zamanında body'nin tam türünü otomatik olarak çıkarır.
struct ContentView: View {
var body: some View {
VStack {
Text("Merhaba")
.font(.title)
Button("Bana dokun") {
print("Dokunuldu")
}
}
.padding()
}
}
Derleyici, body'yi ModifiedContent<VStack<TupleView<(Text, Button<Text>)>>, Padding> olarak çıkarır. Geliştirici some View görür. Düzeni VStack'ten HStack'a değiştirirseniz, derleyici otomatik olarak türü yeniden çıkarır — manuel düzenleme gerekmez. Opaque type'ın büyüsü budur: geliştirici arayüz mantığına odaklanır, kompozisyon türlerine değil.
Sıkça Sorulan Sorular
Opaque Type, some anahtar kelimesiyle bildirilen ve çağıran koddan somut uygulamayı gizleyen bir türdür. Derleyici tam türü bilir, ancak fonksiyonu kullanan geliştirici yalnızca protokolü görür.
some statik kimliğe sahip opaque type'dır: derleyici somut türü bilir. any dinamik dağıtımlı varoluşsal türdür: tür kimliği silinir. Some daha verimlidir, any daha esnektir.
some View, derleyicinin otomatik olarak çıkardığı body'nin karmaşık somut türünü gizler. Bu, geliştiriciyi genel sarmalayıcılardan (VStack, Group, ModifiedContent) oluşan tam türü yazma zorunluluğundan kurtarır.
Evet, Swift 5.7'den itibaren. Parametrelerde some, genel bir parametre üzerinde sözdizimsel şekerdir. Fonksiyon bildirimlerini basitleştirir, özellikle her some parametresinin ayrı bir
Derleyici hata verir: opaque type, tüm dönüş dallarının aynı somut türü döndürmesini gerektirir. Bu, tür kimliğini korumak için kasıtlıdır. Farklı türler döndürmeniz gerekiyorsa, any kullanın.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun