Pattern matching (örüntü eşleştirme) — Swift'in temel bir özelliği olup kodu daha güvenli ve temiz hale getirir. Tarihsel olarak, pattern matching, özellikle ilişkili değerlerle enum'larla daha ifade edici ve güvenli bir şekilde çalışmak için gelişmiştir. Diğer dillerden farklı olarak, Swift iç içe yer alan değerleri doğrudan if, guard, switch ifadelerinde açmaya izin verir.
Sorun: Standart dışı enum'lar, özellikle iç içe ilişkili değerlerle, case yapısında kolayca hata yapabilir veya ana switch'in kısıtlamalarını göz ardı edebilirsiniz. Ayrıca, if case, guard case ve klasik switch kullanımı arasındaki fark sıklıkla net değildir.
Çözüm: Farklı senaryolara bağlı olarak pattern matching için farklı yaklaşımlar uygulamak ve karmaşık iç içe yapılar söz konusu olduğunda isimleri açıkça belirtmek ve where kullanımını kullanmaktır.
Kod örneği:
enum NetworkState { case success(User) case failure(Error, code: Int) case loading(progress: Double) } let state = NetworkState.failure(SomeError(), code: 401) if case let .failure(error, code) = state, code == 401 { print("Yetkisiz: \(error)") } guard case .success(let user) = state else { return } print(user) switch state { case .success(let user): print("Hoş geldiniz, \(user.name)") case .failure(let error, let code) where code == 404: print("Bulunamadı: \(error)") case .failure(_, let code): print("Hata kodu: \(code)") case .loading(let progress): print("İlerleme: \(progress)") }
Anahtar özellikler:
Switch içinde tüm enum case'lerini belirtmezseniz ne olur?
Compiling hata (eğer enum non-optional ise) veya tüm kapsama alınmazsa uyarı/default case gerektirir. Optionals için sadece .some ve .none'ı belirtmek yeterlidir.
İlişkili değerler ve iç içe enumlarla pattern matching yapılabilir mi?
Evet. Ancak sözdizimi karmaşıktır. İç içe değerler için birkaç seviyeyi doğrudan açabilirsiniz:
enum Outer { case inner(Inner) } enum Inner { case item(id: Int) } let e = Outer.inner(.item(id: 5)) if case let .inner(.item(id)) = e { print(id) }
Pattern matching'de guard case ile if case arasındaki fark nedir?
guard case, koşulu kontrol eder ve başarısız olursa çıkış bloğu (return, throw, break) uygular. Genellikle gereksinimler için kullanılır: eşleşmiyorsa çıkın.
if case, işlevden çıkış gerektirmeyen tek satırlık koşul işleyicileri için uygun bir yapıdır.
Geliştirici birden fazla case'e sahip bir enum için switch kullanıyor, ancak yeni bir case'i kapsamıyor. Kod derleniyor, ancak yeni senaryo işlenmiyor ve uygulama çalışma zamanında çöküyor.
Artılar:
Eksiler:
Geliştirici tüm case'leri açıkça kapsıyor, yerel filtreler için where kullanıyor, iç içe değerleri iç içe let aracılığıyla açıyor.
Artılar:
Eksiler: