Es gibt ein großartiges Beispiel für die Umzugssemantik von Rust, die hier dokumentiert ist: Rust Move Semantics auf der Rust By Example-Website
Ich habe ein grundlegendes Verständnis beider Fälle demonstriert. Der erste Grund dafür, wie ein Primitiv einen neuen Alias und das Original haben kann, kann weiterhin verwendet werden, da das Endergebnis eine Kopie ist, da i32
das Copy
Merkmal verwendet. Das macht Sinn für mich.
Außerdem macht das zweite Beispiel aus vielen guten Gründen Sinn, da es mehrere Aliase gibt, die sich auf einen i32
auf dem Heap beziehen. Rust erzwingt Eigentumsregeln und daher kann der ursprüngliche Alias jetzt nicht verwendet werden, da eine neue Bindung erstellt wurde. Dies verhindert Datenrennen, doppelte Frees, etc.
Aber es scheint, dass es einen dritten Fall gibt, über den nicht gesprochen wird. Wie implementiert Rust Bewegungen von Stack-allokierten Strukturen, die das Merkmal Copy
nicht implementieren? Dies wird mit dem folgenden Code veranschaulicht:
Das weiß ich: Im obigen Fall wird Rust die Employee
auf dem Stapel zuweisen . Die obige Struktur implementiert das Copy
-Zeichen nicht und wird daher nicht kopiert, wenn sie einem neuen Alias zugewiesen wird. Das ist sehr verwirrend für mich, wenn die Employee
Struktur auf dem Stack zugewiesen ist und auch nicht das Copy
Merkmal implementiert, wohin / wie bewegt es sich? Wird es physisch in den Stapelrahmen von do_something()
verschoben?
Jede Hilfe wird bei der Erklärung dieses Rätsels geschätzt.
Wird es physisch in den Stapelrahmen von
do_something()
verschoben?
Ja. Nicht Copy
-Typen werden physikalisch genau wie Copy
-Typen verschoben: mit einem memcpy
. Sie haben bereits verstanden, dass primitive Copy
-Typen Byte für Byte an den neuen Speicherort kopiert werden (z. B. neuer Stapel).
Betrachten Sie nun diese Implementierung von Box
:
Wenn Sie
haben %Vor% Dann wird ein i32
auf dem Heap zugewiesen und der Box
speichert den rohen Zeiger auf diesen dem Heap zugeordneten Speicher. Beachten Sie, dass das Box
direkt (der rohe Zeiger innerhalb) direkt auf dem Stapel ist, nicht auf dem Heap! Nur die i32
ist auf dem Heap.
Wenn Box
verschoben wird, ist es memcpy
ed, wie ich gerade gesagt habe. Dies bedeutet, dass der Stack-Inhalt kopiert wird (!!) ... also wird nur der Zeiger Byte für Byte kopiert. Es gibt keine zweite Version von i32
!
Es gibt keinen Unterschied zwischen Copy
und nicht Copy
Typen, wenn es darum geht, sich physisch zu bewegen. Der einzige Unterschied besteht darin, dass der Compiler unterschiedliche Regeln für diese Typen erzwingt.
Tags und Links rust move-semantics ownership-semantics