ProgrammierungMiddle iOS Entwickler

Wie funktionieren Operatorfunktionen (Operatorüberladung als Funktionen) in Swift? Welche Einschränkungen gibt es bei Überladungen und kann man eigene Operatoren erstellen?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

Operatorfunktionen in Swift sind die Möglichkeit, Standardoperatoren (+, -, *, ==, < usw.) zu implementieren oder zu überschreiben sowie eigene Operatoren (z.B. %% oder <|>) zu erstellen. Dazu verwendet man das Schlüsselwort operator in der Funktionsdeklaration. In der Regel werden Operatoren für die Arbeit mit eigenen Typen überladen, um sie syntaktisch komfortabel und intuitiv zu gestalten.

Beispiel für eine Überladung der Addition für die Struktur Vector2D:

struct Vector2D { var x: Double var y: Double } func + (lhs: Vector2D, rhs: Vector2D) -> Vector2D { return Vector2D(x: lhs.x + rhs.x, y: lhs.y + rhs.y) } let v1 = Vector2D(x: 1, y: 2) let v2 = Vector2D(x: 3, y: 4) let sum = v1 + v2 // Vector2D(x: 4, y: 6)

Einschränkungen:

  • Operatoren können nur für eigene Typen oder Kombinationen von Standard- und eigenen Typen überladen werden.
  • Eigene Operatoren können nur aus Zeichen erstellt werden, die in Swift für Operatoren zulässig sind (+*-/&|^%~!=<>.?).
  • Man sollte nicht zu viele neue Operatoren schaffen, um die Lesbarkeit des Codes nicht zu verringern.

Fangfrage.

Kann man einen Operator für Standardtypen überladen, zum Beispiel um die Bedeutung von + für Int zu ändern?

Antwort: Nein, in Swift kann man das globale Verhalten von Operatoren für Standardtypen nicht überschreiben, sondern nur für eigene Typen oder spezifische Kombinationen erweitern. Zum Beispiel:

// Fehler: Die Überladung für Int wird das bestehende Verhalten von + nicht ändern func + (lhs: Int, rhs: Int) -> Int { return lhs - rhs // Funktioniert nicht: Konflikt mit dem bestehenden Verhalten }

Beispiele für reale Fehler aufgrund von Unkenntnis der Feinheiten des Themas.


Geschichte

In einem Projekt wurde ein eigener Operator ** (Exponential) erstellt, der versehentlich eine falsche Priorität hatte, was zu fehlerhaften Berechnungen von Ausdrücken wie 2 + 3 ** 2 führte. Ergebnis: falsche Ergebnisse, schwer zu debuggender Fehler.


Geschichte

In einem Modul mit interner API wurde == für den eigenen Typ überladen, aber das Hashing (Hashable) wurde nicht implementiert, was zu inkorrektem Verhalten von Sammlungen wie Set und Dictionary führte, bei denen Instanzen als unterschiedlich gezählt wurden, obwohl sie logisch gleich waren.


Geschichte

Bei der Erstellung eines eigenen Operators vergaßen die Benutzer, seine Bedeutung zu dokumentieren. Ein neuer Entwickler verstand die Semantik des Operators falsch und wandte ihn auf ungeeignete Daten an, was schwer fassbare logische Fehler in der Geschäftslogik verursachte.