2016-03-30 7 views
1

So sagen, ich habe eine Vector Struktur:Mutating Infix Funktionen für Structs Swift

struct Vector 
{ 
    var x: Double = 0 
    var y: Double = 0 

    init(x: Double, y: Double) 
    { 
     self.x = x 
     self.y = y 
    } 
} 

Und ich schaffen eine Infix Funktion, die zwei Vector Strukturen ergänzt:

func +(left: Vector, right: Vector) -> Vector 
{ 
    return Vector(left.x + right.x, left.y + right.y) 
} 

Dieses gut funktioniert, aber dann, wenn Ich möchte eine Infix-Funktion erstellen, die zwei Vectors zusammen addiert und den linken Wert auf das Ergebnis setzt (wie +=), dann funktioniert es nicht:

func +=(left: Vector, right: Vector) 
{ 
    left.x += right.x 
    left.y += right.y 
} 

Wenn ich es in meinem Code versuche, tut es nichts. Wenn ich die Vector Struktur in eine Klasse ändere, dann funktioniert es.

Ich weiß, dass Swift kopiert structs und Referenzen classes, gibt es eine Möglichkeit, dies zu tun, oder ist das unmöglich?

Vielen Dank im Voraus!

Antwort

2

In Ihrer += Funktion auf seiner aktuellen Form, Sie versuchen, die Mitglieder eines unveränderlichen Wert zu mutieren Typ, die selbst unveränderlich sind. Wenn Sie in der Funktionssignatur das Schlüsselwort inout zu left hinzufügen, wird dieser Werttyp änderbar und seine Mutation wird über inout: s Copy-in-copy-out-Verhalten aktualisiert (Compiler-Optimierung: in der Praxis durch Verweis, um Kopieraufwand zu vermeiden), danach funktioniert Ihre += Funktion wie beabsichtigt.

func +=(inout left: Vector, right: Vector) 
{ 
    left.x += right.x 
    left.y += right.y 
} 

Der Grund, warum Ihre ursprüngliche Funktion für Klassenarten funktioniert, ist, dass die Mitglieder eines unveränderlichen Referenztyps selbst veränderbar sind; nur die Referenz selbst darf nicht mutiert sein.

2

einfach den inout Parameter für linke param hinzufügen, so dass der Wert wird gespeichert:

func += (inout left : Vector, right: Vector) 
{ 
    left.x += right.x 
    left.y += right.y 
}