Swift’de Hashable ve Equatable

Aytuğ
2 min readMar 29, 2021

--

Selamlar, bu yazımda sizlerle Swift dilinde Hashable ve Equatable protokollerine ne zaman ihtiyaç duyabileceğimizi, nasıl kodumuza uygulayabileceğimizi paylaşacağım. Yazılan örnek kodlar Stanford University School of Engineering, 2017 yılı güz döneminin CS193P kodlu Developing Apps for iOS dersinden alınmıştır.

Bir dictionary oluşturduğumuzda key tarafını Int, String gibi tanımlayabiliyoruz ki genellikle bu şekilde tanımlıyoruz. Peki kendi oluşturduğumuz bir sınıfı key olarak tanımlamak istersek,

Dictionary<Key: Hashable, Value>

gibi bir hata almamız kaçınılmaz. Bu hata bizim oluşturduğumuz Card yapımızın Hashable olmadan key olarak tanımlayamayacağımızı söylüyor. Demek ki daha önceden key olarak tanımlamaya alıştığımız Int, String gibi yapılar Hashable imiş. Peki biz kendi yapımızı veya sınıfımızı Hashable yapabilir miyiz?

Önce mevcut Card yapımızı bir tanıyalım.

struct Card {    var isFaceUp = false    var isMatched = false    var identifier: Int    private static var identifierFactory = 0    private static func getUniqueIdentifier() -> Int {       identifierFactory += 1       return identifierFactory    }    init() {       self.identifier = Card.getUniqueIdentifier()    }}

Bu yapıya Hashable protokolünü verelim ve protokolün bize sağladığı fonksiyon ile yapımızı Hashable’a uygun hale getirelim.

struct Card: Hashablefunc hash(into hasher: inout Hasher) {    hasher.combine(identifier)}

Bu kadar kısa bir işlem ile Dictionary’lerde kendi yapılarımızı key olarak verebileceğiz. Her seferinde key olarak yapılarımızın özelliklerini verip sonrasında aynı nesneyi çağırmak için listelerde arama yapmamıza gerek kalmadı.

Aynı şekilde işlerimizi struct ve class’lar ile halledebilmek için Hashable’ın da kalıtım aldığı Equatable protokolünü uygulayarak karşılaştırma işlemlerimizi çok daha kısa bir şekilde halledebileceğiz. Her iki yapıyı veya sınıfı karşılaştırırken tek tek property’lerini karşılaştırmak zorunda kalmayacağız. Bir kere tanımlayıp kurallarımızı verdikten sonra daha temiz bir şekilde kodumuzu yazmaya devam edebiliriz.

Zaten Hashable, Equatable’dan kalıtım aldığı için direkt olarak Card sınıfına Equatable protokolünün sağladığı fonksiyonu implement edebiliriz.

static func ==(lhs: Card, rhs: Card) -> Bool {    return lhs.identifier == rhs.identifier}

Bizden doğal olarak Bool bir değer döndürmemiz bekleniyor. Yapımızdaki hangi property’lere göre eşitliğin sağlanacağını tanımlayarak eşitlik sorgularını nesnelerimiz üzerinden yapabiliriz. Örneğin;

if firstCard.identifier == secondCard.identifier {
//some codes
}

yerine,

if firstCard == secondCard {
//some codes
}

şeklinde kullanabiliriz. Özellikle 2 nesne eşitliği için birçok property kontrol edilecek durumlarda bu protokol hayatımızı daha kolay bir hale getiriyor.

Bu protokollerin getirdiği kolaylıkları sizlerle paylaşmaya çalıştım. İyi, kötü feedback’lerinizi esirgemeyin. Özellikle kötü feedback’leri 👻

--

--