ProgramlamaSwift Orta/Üst Düzey

Swift'te protokol bileşimi nedir, pratikte nasıl çalışır ve ne zaman çoklu kalıtım veya protokolün normal kullanım yerine kullanılmalıdır?

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

Cevap.

Protokol bileşimi, Swift'te aynı anda birden fazla protokole uyması gereken bir tür oluşturmayı sağlayan bir mekanizmadır. Bu, Swift'te sınıflar için olmayan çoklu kalıtımın alternatif bir yoludur.

Sorunun Tarihi

Objective-C, çoklu kalıtımı yalnızca protokoller için destekliyordu, ancak sınıflar için değil. Swift, yeni abstractions oluşturmak için protokollere ve bunların kombinasyonuna vurgu yaparak bu geleneği sürdürüyor.

Problem

Programcılar sıklıkla, davranışları birden fazla abstractions tarafından tanımlanan bir tür oluşturma görevini üstlenir. Çoklu kalıtım kaçınılmaz olarak hiyerarşi çatışmalarına yol açar, bu Swift'te protokoller ve protokol bileşimi sayesinde güvenli bir şekilde çözülür.

Çözüm

Swift'te protokolleri '&' operatörü ile birleştirmek mümkündür. Bu, birden fazla protokole aynı anda uyması gereken değişkenler veya fonksiyon parametreleri oluşturmayı sağlar.

Kod örneği:

protocol Drivable { func drive() } protocol Flyable { func fly() } struct FlyingCar: Drivable, Flyable { func drive() { print("Driving") } func fly() { print("Flying") } } func testVehicle(_ vehicle: Drivable & Flyable) { vehicle.drive() vehicle.fly() } testVehicle(FlyingCar())

Anahtar noktalar:

  • '&' operatörü, bir değişken veya fonksiyon parametresi için birden fazla protokolü birleştirmeyi sağlar
  • Sınıflar, yapılar ve enum'lar için de çalışır
  • Ara türler oluşturmadan gerekli davranışları açıkça tanımlama imkanı sağlar

Zor Sorular.

Sadece bir protokolü uygulayan bir nesneyi protokol bileşeni olan bir parametreye geçirebilir miyiz?

Hayır, nesne, bileşimde yer alan tüm protokolleri uygulamak zorundadır; aksi takdirde derleyici hata verir.

Kod örneği:

// struct Car: Drivable {} — testVehicle'a geçirilemez, çünkü fly() uygulanmamış

Protokol bileşimi, sadece değerlere değil türlere de uygulanır mı?

Protokol bileşimi değerlere (değişkenler, fonksiyon parametreleri) uygulanır, ancak bir nesne türü tanımlamada kullanılmaz (örneğin, yeni bir türü herhangi bir „protokol bileşimi” olarak ilan etmek mümkün değildir - yalnızca değişken).

Kod örneği:

var obj: SomeProtocol & AnotherProtocol // geçerli // typealias MyType = SomeClass & AnotherProtocol // hata

& ile sınıfları ve protokolleri birleştirmek mümkün mü?

Evet, ancak bir sınıf türü (sınıf veya onun miras aldığı) sol tarafta yalnızca bir tane olabilir, diğerleri yalnızca protokoller olmalıdır; aksi takdirde derleyici hata verir.

Kod örneği:

class A {} protocol B {} // func f(obj: A & B) {} // geçerli // func f(obj: A & AnotherClass & B) {} // hata! Yalnızca bir sınıf türüne izin verilir

Yaygın Hatalar ve Antipatternler

  • Sınıfların çoklu kalıtım gibi çalışmasını beklemek
  • Gerekmedikçe bileşimi kullanmak, bir protokol yeterliyken
  • Dış kütüphaneler ve protokol bileşimi kullanıldığında sözleşmelerin ihlali

Gerçek Hayat Örneği

Olumsuz Durum

Projede katmanlar arasında veri iletimi için protokol bileşimi kullanan nesneler kullanılıyor, oysa sadece bir protokol yeterliydi:

func present(item: Displayable & Serializable) { ... }

Artıları:

  • Esnek ve genişletilebilir bir arayüz Eksileri:
  • Karmaşıklık ve kafa karışıklığı, eğer çoğu iletilen nesne tüm özellikleri gerektirmiyorsa

Olumlu Durum

Protokol bileşiminin yalnızca açık durumlarda kullanılması — örneğin, Genel serileştirme için hem Codable hem de Identifiable'ı aynı anda destekleyen nesnelerin işlenmesi:

func save<T: Codable & Identifiable>(_ item: T) { ... }

Artıları:

  • Tür gereksinimlerinin net bir tanımı
  • Hataların en aza indirilmesi Eksileri:
  • Fonksiyonun imzasını biraz karmaşıklaştırabilir