Swift’te Phantom Types (Hayalet Türler) 👻

Hasan Ali Şişeci
Appcent
Published in
4 min readOct 11, 2023

Bu makalede adım adım hem phantom types’ın ne olduğunu hem de neden kullanışlı olabileceklerini anlatacağım.

Swift hepimizin bildiği gibi type safety bir dildir. Bu, Swift’in, kodunuzun çalışabileceği değer tipleri konusunda net olmanıza yardımcı olduğu anlamına gelir.

Ancak Swift’in sağladığı bu güvenlikten daha fazlasını kodumuzda sağlamak istersek ne yapmalıyız? Burada generic olarak modellerimize ekleyebileceğimiz ve aslında kullanmadığımız bize bir güvenlik katmanı sağlayan Phantom Types’ı hemen incelemeye başlayalım.

Hemen kafamızda daha somut bir şeyler oluşması için örneklendirerek anlatmaya başlayalım. Kendi oluşturduğumuz iki modelin içerisinde karşılaştırılmaması gereken değerleri karşılaştırdığımızda build almadan önce compile aşamasında Xcode’un bize uyarı vermesini istediğimizi düşünelim.

İlk olarak Person adında struct oluşturalım. Bu struct’ın içinde bir id ve name propertysi olsun. Id parametresinin unique olması için UUID olarak set edelim.

Şimdi de Phone adında bir başka struct yaratalım. Person gibi unique bir id değerine ve farklı olarak da brand ve model olarak iki farklı string property’e sahip olsun.

Daha sonra kurguladığımız bu struct’lar ile şöyle bir fonksiyon kullandığımızı hayal edelim. Bu fonksiyonda bir Person objesi yaratarak, fonksiyona parametre olarak gelen Phone array’ini filtreleyerek bir “filtered” phone objesi yakalamaya çalışıyoruz.

Evet aslında buraya kadar kodsal olarak bir hatamız yok. Ama mantık olarak bir Person objesi ile bir Phone objesinin id parametresinin uyuşması ne kadar mantıklı? Burada Xcode elbette bize bir hata dönmeyecek çünkü karşılaştırılan iki id değeri de UUID tipinde ve hiçbir sıkıntı yok. Bu bir sorundur çünkü böyle bir kod hiçbir anlam ifade etmez ve bir hataya yol açacağı garantidir. Phantom types’da tam olarak burada karşımıza çıkıyor.

ID adında yeni bir struct oluşturuyoruz. Ve burada bir UUID saklıyoruz. Ve bu yapıya bir generic parametre ekliyoruz. Burada generic olarak eklediğimiz yapıyı kullanmamız garip gelebilir fakat az sonra anlam kazanacak.

Daha sonra Person ve Phone structlarımızda kullandığımız UUID ler yerine artık kendi oluşturduğumuz ID struct’ımızı kullanacağız ve generic parametre sayesinde id değerlerinin tiplerinin aynı olmamasını sağlayacağız.

Bu işlem sayesinde artık yanlışlıkla bir Person objesinin id’si ile bir Phone objesinin id’sini karşılaştırmaya çalışırsak compile-time error ile karşılaşıcaz. Ve böylece gözden kaçan yanlış bir logic kurmamış olucaz. Ve aslında adından da anlaşılacağı üzere çok göz önünde bulunmadan hayat kurtaran bu yapılara da hayalet tür (phantom type) diyoruz.

Yani bu tipler runtime’da herhangi bir veri taşımaz. Ancak, bu tipler belirli bir türü temsil etmek için kullanılır ve genellikle bu türün üzerinde belirli operasyonları gerçekleştirmek için kullanılan güvenli bir yol sağlar. Phantom types, tip bilgisi taşımayan, yalnızca tip güvencesi sağlayan tiplerdir. Bize sağladıkları yararları 3 ana başlıkta özetleyebiliriz:

  • Tip Güvenliği
  • Compile-Time Kontrolü
  • Daha Okunabilir ve Bakımı Kolay Kod

Aslına bakarsak anlatacaklarım bu kadardı fakat bir örnek ile biraz daha pekiştirmek istiyorum.

Burada Employee adında bir struct oluşturuyor ve içerisinde name ve role adında iki string değer saklıyorum. Ardından boolean geri dönüş tipine sahip bir fonksiyon yazıyorum ve oluşturduğum iki Employee objesini karşılaştırıyorum ve bu karşılaştırma ile fonksiyonun dönüşünü sağlıyorum.

Evet buraya kadar yine okeyiz, hatalı bir kod yazmadık fakat logic olarak düşündüğümüz iki farklı role sahip çalışanın karşılaştırılması ne kadar doğru olur? Bu karşılaştırma pek de mantıklı değil aslında.

Burada tekrar phantom types’ı hatırlıyorum ve bu sefer enum yardımıyla bu kodu revize ediyorum.

Artık Employee içerisinde generic olarak Role parametresi alıyor ve bu şekilde init ediliyor. Bu karşılaştırmanın ardından Xcode bize aşağıdaki compile-time error dönüyor ve bu iki objenin karşılaştırılamayacağını farklı türde olduklarını söylüyor.

Bir yazının daha sonuna geldik. Yeni öğrendiğim bu konuyu dilim döndüğünce sizlere anlatmaya çalıştım. Umarım hayalet türler işlerinizi kolaylaştırır ve daha güzel kodlar yazmanızı sağlar. Başka bir yazıda görüşmek üzere.

Ayrıca Phantom Types’ı öğrendiğim kaynağa buradan ulaşabilirsiniz. https://www.youtube.com/watch?v=uAlBRGNycdw

--

--