Soru Tarihi: Tür silinmesi (type erasure) - Swift'te, ilişkili türler veya Self gereksinimleri olan protokollerin kısıtlamalarına bir yanıt olarak ortaya çıkan bir modeldir. İlişkili türler içeren bir protokol, tür silinmesi olmadan doğrudan tür olarak kullanılamaz, çünkü derleyici belirli bir uygulamanın ne olduğunu bilemez. Bu, veri kapları, koleksiyonlar, akışlar gibi yaratırken sıkça karşılaşılan bir durumdur, burada soyutlama önemlidir.
Sorun: Eğer ilişkilendirilmiş tür ile bir protokol varsa, örneğin:
protocol Animal { associatedtype Food func eat(_ food: Food) }
Animal türünde bir değişken tanımlamak mümkün değildir. Farklı somut türlere soyutlama aracılığıyla erişim sağlayan "silinmiş bir kapsayıcı" türe ihtiyacımız vardır:
let zoo: [any Animal] // Derleme hatası
Çözüm: Tür silinmesi, sarmalayıcılar (örneğin, Box modeli veya struct AnyXxx) kullanılarak gerçekleştirilir ve gerçek türün ayrıntılarını gizleyerek tek bir arayüz sağlar:
struct AnyAnimal<F>: Animal { private let _eat: (F) -> Void init<A: Animal>(_ base: A) where A.Food == F { _eat = base.eat } func eat(_ food: F) { _eat(food) } }
Artık aynı Food ile farklı Animal uygulamalarını saklayabiliriz:
let animals: [AnyAnimal<Grass>] = [AnyAnimal(Cow()), AnyAnimal(Sheep())]
Temel Özellikler:
İlişkili türü olmayan bir protokolü tür özelliği veya dizisi olarak kullanmak mümkün mü?
Hayır, mümkün değil. Derleyici, tüm ilişkili türlerin kesinleştirilmesini gerektirir. Örneğin, aşağıdaki kayıt bir hataya neden olacaktır:
let array: [Animal] // Hata: 'Animal' yalnızca bir genel kısıtlama olarak kullanılabilir
Tür silinmesi, mirası (inheritance) ikame edebilir mi?
Hayır, tür silinmesi mirasın tam bir ikamesi değildir. İlişkili türler için soyutlama sorununu çözerken, miras sınıflar arasında ortak mantık ve kod yeniden kullanımı uygulamaları için kullanılır.
Tür silinmesi (type erasure) kapsayıcısının içindeki tüm protokol yöntem ve özelliklerini gerçekleştirmek gerekli mi?
Evet, zorunludur. Tür silinmesi, kapsayıcı protokolün dış arayüzünü tamamen tekrar etmesi durumunda çalışır, aksi takdirde bazı işlevler kullanılamaz.
Bir projede tüm veri kaynakları ile çalışmalar tür silinmesi üzerinden yürütülmektedir, ihtiyaç olmaksızın. Kodun bakımı zorlaşır, yeni geliştiriciler karışıklık yaşar.
Artılar:
Eksiler:
Tür silinmesi, farklı yükleme stratejilerini (ağ, yerel) kapsayan veri kaynağının soyutlaması için yalnızca uygulanmaktadır ve her biri kendi türlerine sahiptir. Diğer tüm kod açıktır.
Artılar:
Eksiler: