ProgramlamaiOS geliştirici

Swift'te yapıların ve ilişkili değerleri olan enum'ların pattern matching'i nasıl çalışır? `if case`, `guard case`, `switch` arasındaki fark nedir ve karmaşık enum'larda case adının ve iç içe geçmişliğin rolü nedir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

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:

  • Pattern matching, switch, if case, guard case ve ayrıca let/var bağlama ile mümkündür.
  • where aracılığıyla filtreleme yapabilirsiniz.
  • Switch içinde pattern matching, tüm enum case'lerini açıkça tanımlamanıza olanak tanır ve atlanan senaryoların olmamasını garanti eder.

Kandırmaca Soruları.

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.

Tipik hatalar ve anti-patentler

  • Switch içinde tüm enum case'leri için kapsama geçmek — hatalara ve çöküşlere yol açar.
  • İç içe değerleri açarken hatalar: karışık isimler veya iç içe geçmişlik seviyeleri.
  • Optional değerler için if/switch kullanımı, .none-case'in göz önünde bulundurulmaması nedeniyle senaryonun atlanmasına neden olur.

Hayat Örneği

Olumsuz durum

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:

  • default aracılığıyla minimum bir işleyiciyi eklemek kolaydır.

Eksiler:

  • Atlanan senaryolar, nedenini izlemek zor.
  • Yeni case'ler belirdiğinde potansiyel çökme.

Olumlu durum

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:

  • Tam tür güvenliği
  • Tüm senaryolar açıkça tanımlanmış.

Eksiler:

  • Bazen aşırı, kelime yoğun switch veya çift pattern matching.