Wie implementiere ich die Add-Eigenschaft für eine Referenz auf eine struct?
Machte ich eine zwei-element Vector
struct, und ich möchte, um eine überlastung der +
Betreiber.
Machte ich alle meine Funktionen und Methoden-Referenzen, sondern als Werte, und ich will die +
- operator auf die gleiche Weise funktionieren.
impl Add for Vector {
fn add(&self, other: &Vector) -> Vector {
Vector {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
Je nachdem, welche Variante ich versuche, ich erhalte entweder Lebensdauer Probleme oder Abweichungen geben. Insbesondere die &self
argument scheint nicht behandelt, da den richtigen Typ.
Ich habe schon Beispiele gesehen, mit template-Argumente auf impl
sowie Add
, sondern Sie nur dazu führen, dass verschiedene Fehler.
Fand ich Wie kann ein operator überladen werden für die unterschiedlichen RS-Typen und Rückgabe-Werte? aber den code in die Antwort gar nicht funktionieren, wenn ich eine use std::ops::Mul;
an der Spitze.
Ich bin mit rustc 1.0.0-nightly (ed530d7a3 2015-01-16 22:41:16 +0000)
Akzeptiere ich nicht "Sie müssen nur zwei Felder, warum die Referenz" als Antwort; was ist, wenn ich wollte eine 100-element-Struktur? Ich akzeptiere eine Antwort, die zeigt, dass selbst mit einer großen Struktur, die ich sein sollte als Wert übergeben werden, wenn das der Fall ist (ich glaube nicht, dass es, obwohl.) Ich bin daran interessiert zu wissen, eine gute Faustregel für die Struktur, die Größe und die übergabe by-value vs-struct, aber das ist nicht die aktuelle Frage.
RVO nur auf die return-Wert, was bin ich wieder von Wert. Können Sie auf Dokumentation, die zeigt, dass die Merkmale für große Strukturen umgesetzt werden sollten, die von Wert?
Die beste Dokumentation die ich kenne wäre die Buch Kapitel über die Rückgabe von Zeigern. Aber ich erstellt ein Beispiel für das hinzufügen einer großen struct und überprüft die erzeugten LLVM (leicht gereinigt):
(%struct.Big* sret, %struct.Big*, %struct.Big*)
. Ich behaupte nicht, ein LLVM-Experte, aber das sieht aus wie es ist, automatisch Entnahme und Rückgabe per Referenz.Die Dokumentation bezieht sich auch auf den Rückgabewert, die ich Stimme Sie sollte nicht eine ref. In der Tat, die Dokumentation verwendet, um zu sagen, dass Sie sollten nicht verwenden Sie die Zeiger für Eingabe-Parameter, sofern Sie gebraucht, aber das war eigentlich entfernt. Auch ich änderte Ihr Beispiel zu tun, als Verweis übergeben und fand es entfernt die beiden Zuweisungen (
%arg7 = alloca %struct.Big, align 8
und %arg8 = alloca %struct.Big, align 8
) so wie es aussieht für große Strukturen zumindest, Referenzen sind besser.Ich sollte darauf hinweisen, dass ich weniger wissen, als jemand über LLVM, so meine interpretation kann werden alle nass. Auch ein Nachteil der Verwendung von Referenzen zur operator-überladung ist, dass, wenn Sie zufällig nicht haben, Verweise
let c = (&a) + (&b);
ist ziemlich nervig.InformationsquelleAutor Jeremy Sorensen | 2015-01-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie implementieren
Add
auf&Vector
anstatt aufVector
.In der definition, die
Add::add
nimmt immerself
Wert. Aber Referenzen sind Arten wie jede andere1, so dass Sie implementieren können, Züge zu. Wenn ein Merkmal implementiert, die auf einem Referenz-Typ, die Art derself
ist ein Verweis, die Referenz wird als Wert übergeben. Normalerweise als Wert übergeben werden, in Rost bedeutet die übertragung von Eigentum, aber wenn die Referenzen als Wert übergeben werden, Sie sind einfach nur kopiert (oder reborrowed/verschoben werden, wenn es eine veränderbare Referenz), und die nicht die übertragung des Eigentums an der referent (weil ein Verweis nicht seinen eigenen Referenten auf dem ersten Platz). Bedenkt man all dies, macht es Sinn, fürAdd::add
(und viele andere Betreiber) nehmenself
von Wert: wenn Sie brauchen, um das Eigentum der Operanden, die Sie umsetzen könnenAdd
auf structs/enums direkt, und wenn Sie nicht, können Sie implementierenAdd
auf Referenzen.Hier
self
ist der Typ&'a Vector
, denn das ist die Art wir implementierenAdd
auf.Beachten Sie, dass ich auch die angegebenen
RHS
type-parameter mit einem anderen Leben zu betonen, die Tatsache, dass die Lebensdauern der zwei input-Parameter, die nicht verknüpft sind.1 Eigentlich Referenztypen gilt die Besonderheit, dass Sie implementieren können, - Eigenschaften für Verweise auf Typen in Ihrer Kiste (D. H., wenn Sie erlaubt sind zu implementieren, die ein Merkmal für
T
, dann sind Sie auch erlaubt, um es zu implementieren für&T
).&mut T
undBox<T>
haben das gleiche Verhalten, aber das ist nicht wahr im Allgemeinen fürU<T>
woU
ist nicht definiert in der gleichen Kiste.Wow. Erstaunt, dass dies die richtige Antwort ist, und doch ist es. Das fühlt sich alles ziemlich kontraintuitiv. Sie können definieren, Fügen Sie in zwei verschiedene Möglichkeiten, je nachdem, ob es sich um ein Referenz-oder nicht fühlt sich an wie ein Rezept für ärger.
InformationsquelleAutor Francis Gagné