Ich möchte diese Struktur schreiben:
%Vor% Das B.c
sollte von A.c
ausgeliehen werden.
Das habe ich versucht:
%Vor%Aber es scheitert:
%Vor%Ich habe die Rust-Dokumentation über den Besitz gelesen, aber ich weiß immer noch nicht, wie ich es beheben kann.
Wenn es hilfreiche Artikel gibt, lassen Sie es mich in den Kommentaren wissen.
Es gibt tatsächlich mehr als einen Grund, warum der obige Code fehlschlägt. Lass es uns ein wenig durchbrechen und erkunde ein paar Möglichkeiten, wie du es reparieren kannst.
Zuerst entfernen wir new
und versuchen, eine Instanz von A direkt in main zu erstellen, so dass Sie sehen, dass der erste Teil des Problems nichts mit Lebenszeiten zu tun hat:
Dies schlägt fehl mit:
%Vor% Wenn Sie c1
auf c
zuweisen, wird der Besitz auf c
verschoben (d. h. Sie können nicht mehr über c1
, nur über c
darauf zugreifen). Dies bedeutet, dass alle Referenzen auf c1
nicht mehr gültig sind. Aber Sie haben &c1
immer noch im Umfang (in B), also kann rustc Sie diesen Code nicht kompilieren lassen.
Der Compiler deutet auf eine mögliche Lösung in der Fehlermeldung, wenn der Typ C
nicht kopierbar ist. Wenn Sie eine Kopie von C erstellen könnten, wäre Ihr Code dann gültig, weil das Zuweisen von c1 zu c eine neue Kopie des Werts erstellen würde, anstatt den Besitz der ursprünglichen Kopie zu verschieben.
Wir können dies versuchen und C kopierbar machen, indem wir seine Definition wie folgt ändern:
%Vor%Jetzt funktioniert der obige Code. Beachten Sie, dass das, was @ matthieu-m in seinem Kommentar sagt, immer noch wahr ist. Wir können nicht sowohl den Verweis auf einen Wert als auch den Wert selbst in B speichern (wir speichern hier einen Verweis auf einen Wert und einen COPY des Werts). Das ist jedoch nicht nur für Strukturen, sondern auch für das Ownership.
Wenn Sie nun C nicht kopierbar machen wollen (oder nicht können), können Sie stattdessen Referenzen in A und B speichern.
%Vor% Alles gut dann? Nicht wirklich ... wir wollen die Erstellung von A
zurück in eine new
Methode verschieben. Und da werden wir mit den Lebensläufen in Schwierigkeiten geraten.
Lassen Sie uns die Erstellung von A zurück in ein Impl ziehen.
wie erwartet, hier ist unser Lebenszeitfehler:
%Vor% Das liegt daran, dass c1 am Ende der new
-Methode zerstört wird, daher können wir keine Referenz darauf zurückgeben.
Eine mögliche Lösung besteht darin, C außerhalb von new
zu erstellen und es als Parameter zu übergeben. Kompletter Code hier:
Nach dem Überprüfen mit Manishearth und eddyb auf dem IRC #rust glaube ich, dass es für eine Struktur nicht möglich ist, einen Verweis auf sich selbst oder einen Teil von sich selbst zu speichern. Was Sie also versuchen, ist in Rusts Typsystem nicht möglich.