Swift 3 Associated Type Generic Protocol typealias associatedtype

Dikkat: Aşağıdaki yazı yakında yazımı tamamlanacak olan Swift kitabımdan sınırlı bir alıntıdır izinsiz kopyalanıp kullanılamaz.

Swift’te fonksiyonların, class’ların, structure’ların ve enum’ların generic olabileceği daha önce de belirtilmişti. Ancak protokoller bu durumun bir istisnasıdır yani bir protokol generic olamaz. Bu nedenle aşağıdaki işlem “Protocols don’t allow generic parameters; use associated types instead” hatası ile sonuçlanır.

protocol PSample<T>

{

}

Hata mesajından da anlaşılabileceği gibi bu durumda uygulanması gereken çözüm; associated type kullanımıdır. Aşağıdaki örneği inceleyiniz:

protocol Repository

{

// Associated type tanımlamak

typealias Entity

// associatedtype Entity // Xcode 7.3+

func Save(e:Entity)

func Delete(e:Entity)

func GetRecord() -> Entity

func GetTable() -> [Entity]

}

Repository isimli protokol, temel veritabanı işlemlerini entity türünden bağımsız olarak soyutlamak için yazılmıştır. Burada typealias anahtar sözcüğü ile tanımlanan Entity aslında bir tür generic parametredir. Bu protokolü implemente eden özgün repository sınıfları hangi entity için yazılmışlarsa Entity yerine o sınıfı kullanabilir. Aşağıdaki örnekte Customer isimli sınıf Entity yerine geçecek olan sınıftır.

class Customer {

}

class CustomerRepository : Repository

{

func Save(e:Customer)

{

}

func Delete(e:Customer)

{

}

func GetRecord() -> Customer

{

return Customer()

}

 

func GetTable() -> [Customer]

{

return []

}

}

İpucu: typealias anahtar sözcüğünün iki farklı anlamda (türlere takma isim atamak ve associated type tanımlamak için) kullanılıyor olması bir tür karışıklığa neden olmaktaydı. Bu karışıklığı gidermek için Swift 3 versiyonunda associated type tanımlama amacıyla ile associatedtype isimli yeni bir anahtar sözcük gündeme getirildi. typealias anahtar sözcüğünün bu amaçla kullanımı Xcode 7.3 güncellemesi sonrasında bu gerekçeyle bir uyarıya neden olmaktadır.

Reklamlar

Swift Generic & Contraint Kullanımı

Dikkat: Aşağıdaki yazı yakında çıkacak olan Swift kitabımdan bir alıntıdır izinsiz kopyalanıp kullanılamaz.

Swift’te generic bir fonksiyon ya da sınıfa herhangi bir türde açılım yapılabilir. Ancak geliştirici şayet isterse açılım yapılabilecek türlerde kısıtlamaya gidebilir. Kısıtlamalar, açılım yapılabilecek türlerin belirli bir taban sınıftan türetilmesi ya da belirli bir protokolü implemente etmesi şartına dayandırılabilir. Örneğin aşağıdaki Foo() isimli fonksiyonun ilk parametresine açılım yapacak olan türün CKisitlama isimli sınıftan türetilmesi, ikinci parametresi ise PKisitlama isimli protokolden implemente edilmesi gereklidir.

class CKisitlama {

}

class Sinif1 {

}

class Sinif2 : CKisitlama {

}

protocol PKisitlama {

}

class CSinif3 {

}

class CSinif4 : PKisitlama {

}

func Foo<A: CKisitlama, Z: PKisitlama>(p1:A, p2:Z)

{

}

////// TEST ///////

Foo(Sinif1(), p2: CSinif3()) // Geçersiz!!!

Foo(Sinif2(), p2: CSinif4())

Sinif1 ve Sinif3 türündeki nesneler gerekli şartları sağlamadıkları için A ve Z yer tutucuları için açılım yapamazlar.

where anahtar sözcüğü

Swift’te kısıtlamalar sadece generic fonksiyonlar için değil aynı zamanda generic türler için de belirtilebilir. Kısıtlamayı aşma koşulu ise yine belirli bir sınıftan türetme ya da belirli bir protokolü implemente etme şeklinde kurgulanır. Generic türün bildiriminde <> içerisinde yazılan yer tutucu(lar) için where anahtar sözcüğünden sonra bir veya daha fazla sayıda kısıtlama belirtilebilir. Örneğin aşağıdaki Controller isimli sınıfta T yerine PRepository ve PTestable protokollerini implemente eden bir tür kullanılabilir.

protocol PRepository

{

}

 

protocol PTestable

{

}

 

class CRepository1

{

}

 

class CRepository2 : PRepository

{

}

 

class CRepository3 : PRepository, PTestable

{

}

 

class Controller<T where T: PRepository, T: PTestable>

{

}

var cnt = Controller<CRepository3>()

Bu örnekte CRepository1 ve CRepository2 gerekli şartları sağlamadığı için açılım yapma amacıyla kullanılamayacak sınıflardır.

C# where keyword ile generic tiplerde açılım kısıtlaması

C# dilinde generic bir türe herhangi bir türde açılım yapılabilir. Ancak geliştirici şayet isterse açılım yapılabilecek türlerde kısıtlamaya gidebilir. Bu kısıtlama açılım yapılabilecek türlerin belirli bir taban sınıftan türetilmesi ya da belirli bir arayüzü implemente etmesiyle gerçekleştirilir. Örneğin aşağıdaki kod’da CBase sınıfından türetilen veya ISample’dan implemente edilen sınıflarla yapılacak açılımlar geçerli diğerleri ise kısıtlama nedeniyle geçersizdir. İnceleyiniz :

Okumaya devam et

Java’da Generic Türler

    Yazılım mühendisliğinde türden bağımsız işlemler yapabilme amacı ile geliştirilen tekniklerin çoğu zaman performansa olan yansımaları olumsuzdur. Sözgelimi türden bağımsız sıralama işlemleri için kullanılan QuickSort isimli algoritma, içsel çalışma biçimi nedeni ile türe özgü sıralama işlemleri yapan diğer algoritmalara izafeten yavaş çalışmaktadır.

Okumaya devam et