Das Schlüsselwort inout in Swift ermöglicht es einer Funktion, den Wert eines übergebenen Parameters direkt (per Referenz) zu ändern, anstatt mit einer Kopie zu arbeiten. Dies ist ähnlich wie pass-by-reference in einigen anderen Sprachen.
Beispiel:
func increment(_ value: inout Int) { value += 1 } var x = 10 increment(&x) // Jetzt ist x == 11
var), let kann nicht übergeben werden.Frage: Kann man eine Eigenschaft einer Struktur an eine Funktion mit einem inout-Parameter übergeben, wenn die Struktur Teil eines anderen Objekts ist?
Antwort: Nein, denn Swift verbietet den gleichzeitigen Zugriff auf dasselbe Attribut innerhalb einer Anweisung (Exclusive Access to Memory), um race conditions und undefiniertes Verhalten zu vermeiden. Beispiel:
struct Point { var x: Int var y: Int } var p = Point(x: 1, y: 2) increment(&p.x) // ok increment(&p.y) // ok // increment(&p.x, &p.x) // führt zu einem Fehler
Geschichte
In einem Projekt versuchte ein Entwickler, dieselbe Variable gleichzeitig an zwei Funktionsparameter mit inout-Modifizierer zu übergeben, was zu einem Kompilierungsfehler führte. Dies zwang ihn, die Architektur der Funktion zu überdenken und die Änderungen in zwei Schritte aufzuteilen.
Geschichte
Der Implementierer änderte ein Array über einen inout-Parameter innerhalb einer Schleife, was zu unerwarteten Ergebnissen führte, da Swift den Inhalt bei der Übergabe kopiert und die Änderungen nicht zwischen den Schleifen synchronisiert wurden.
Geschichte
Der Entwickler erwartete, dass inout-Parameter immer "per Referenz" arbeiten würden, stieß jedoch auf die copy-in/copy-out Semantik bei der Arbeit mit Klassen und Strukturen, weshalb nicht alle Änderungen gespeichert wurden, wenn eingebettete Objekte von Strukturen geändert wurden.