Wie verschiebt Rust Stack-Variablen, die nicht kopierbar sind?

8

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:

%Vor%

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.

    
Ralph Caraveo 26.03.2016, 01:46
quelle

1 Antwort

6
  

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 :

%Vor%

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.

    
Lukas Kalbertodt 26.03.2016, 02:05
quelle