.count }.reduce(0, +) return Int(round(Double(size) / Double(count.toIntMax()))) } }

Jetzt können wir die durchschnittliche Größe jeder Sammlung von Warteschlangen berechnen (Array, Set usw.). Ohne Protokollerweiterungen hätten wir diese Methode jedem Sammlungstyp separat hinzufügen müssen.

In der Swift-Standardbibliothek werden Protokollerweiterungen verwendet, um beispielsweise Methoden wie map, filter, reduce usw. zu implementieren.

Wertschöpfungskette des Internets der Dinge
extension Collection { public func map(_ transform: (Self.Iterator.Element) throws -> T) rethrows -> [T] { } }

Protokollerweiterungen und Polymorphismus

Wie bereits erwähnt, können wir mit Protokollerweiterungen Standardimplementierungen einiger Methoden und neue Methodenimplementierungen hinzufügen. Aber was ist der Unterschied zwischen diesen beiden Merkmalen? Kehren wir zum Fehlerbehandler zurück und finden es heraus.

protocol ErrorHandler { func handle(error: Error) } extension ErrorHandler { func handle(error: Error) { print(error.localizedDescription) } } struct Handler: ErrorHandler { func handle(error: Error) { fatalError('Unexpected error occurred') } } enum ApplicationError: Error { case other } let handler: Handler = Handler() handler.handle(error: ApplicationError.other)

Das Ergebnis ist ein schwerwiegender Fehler.

Entfernen Sie nun das handle(error: Error) Methodendeklaration aus dem Protokoll.

protocol ErrorHandler { }

Das Ergebnis ist dasselbe: ein schwerwiegender Fehler.

Bedeutet dies, dass es keinen Unterschied zwischen dem Hinzufügen einer Standardimplementierung der Protokollmethode und dem Hinzufügen einer neuen Methodenimplementierung zum Protokoll gibt?

Nein! Es gibt einen Unterschied, den Sie sehen können, indem Sie den Typ der Variablen handler ändern von Handler zu ErrorHandler.

let handler: ErrorHandler = Handler()

Jetzt lautet die Ausgabe an die Konsole: Der Vorgang konnte nicht abgeschlossen werden. (ApplicationError-Fehler 0.)

Wenn wir jedoch die Deklaration der Handle-Methode (Fehler: Fehler) an das Protokoll zurückgeben, ändert sich das Ergebnis wieder in den schwerwiegenden Fehler.

protocol ErrorHandler { func handle(error: Error) }

Schauen wir uns die Reihenfolge an, in der jeweils etwas passiert.

Wenn im Protokoll eine Methodendeklaration vorhanden ist:

Das Protokoll deklariert das handle(error: Error) Methode und bietet eine Standardimplementierung. Die Methode wird in Handler überschrieben Implementierung. Daher wird zur Laufzeit unabhängig vom Typ der Variablen die korrekte Implementierung der Methode aufgerufen.

Wenn die Methodendeklaration im Protokoll nicht vorhanden ist:

Da die Methode im Protokoll nicht deklariert ist, kann der Typ sie nicht überschreiben. Deshalb hängt die Implementierung einer aufgerufenen Methode vom Typ der Variablen ab.

Wenn die Variable vom Typ Handler ist, wird die Methodenimplementierung vom Typ aufgerufen. Wenn die Variable vom Typ ErrorHandler ist, wird die Methodenimplementierung von der Protokollerweiterung aufgerufen.

Protokollorientierter Code: Sicher und dennoch ausdrucksstark

In diesem Artikel haben wir einige der Möglichkeiten von Protokollerweiterungen in Swift demonstriert.

Im Gegensatz zu anderen Programmiersprachen mit Schnittstellen schränkt Swift Protokolle nicht mit unnötigen Einschränkungen ein. Swift umgeht die allgemeinen Macken dieser Programmiersprachen, indem es dem Entwickler ermöglicht, Mehrdeutigkeiten nach Bedarf aufzulösen.

Mit Swift-Protokollen und Protokollerweiterungen kann der von Ihnen geschriebene Code so ausdrucksstark sein wie die meisten dynamischen Programmiersprachen und zur Kompilierungszeit dennoch typsicher sein. Auf diese Weise können Sie die Wiederverwendbarkeit und Wartbarkeit Ihres Codes sicherstellen und Änderungen an Ihrer Swift-App-Codebasis sicherer vornehmen.

Wir hoffen, dass dieser Artikel für Sie nützlich ist und freuen uns über Feedback oder weitere Erkenntnisse.