Ist es möglich, Varianten im Wert einer veränderbaren Referenz auf eine Enum zu setzen?

8

Ist es möglich, Varianten im Wert einer änderbaren Referenz ( &mut E<T> ) ohne zusätzliche Einschränkungen für T zu wechseln, ohne auf unsicheren Code zurückzugreifen?

Das heißt, eine enum gegeben:

%Vor%

Was ist die richtige Art dies zu schreiben:

%Vor%     
Doe 24.02.2017, 06:12
quelle

3 Antworten

7

Ich werde hier ein Stück weit gehen und sagen Nein .

Es ist möglich mit nur einer geringfügigen Änderung der Signatur:

%Vor%

Es ist möglich mit unsafe :

%Vor%

Es ist möglich mit zusätzlichen Grenzen ( Default , oder Clone ):

%Vor%     
Matthieu M. 24.02.2017, 10:55
quelle
1

Als Alternative für diesen speziellen Fall könnten Sie in eine Struktur mit einem T und einer einfachen Enumeration wechseln:

%Vor%     
Shepmaster 15.06.2017 15:26
quelle
0
  

ist es möglich, Varianten im Wert einer änderbaren Referenz zu wechseln

Matthieu M. sagte , die allgemeine Antwort lautet "nein". Der Grund dafür ist, dass dies das Enum in einem unbestimmten Zustand belassen würde, was den Zugriff auf undefiniertes Gedächtnis ermöglichen würde, was es erlauben würde, Rust's Sicherheitsgarantien zu durchbrechen. Nehmen wir als Beispiel an, dass dieser Code ohne Fehler kompiliert wurde:

%Vor%

Das Problem ist, wenn Sie den Wert von self in val verschoben haben, was mit dem Speicher geschehen soll, der T in self darstellt?

Wenn wir die Bits kopiert haben und dann eine Panik in "Dinge geschehen" aufgetreten ist, würde der Destruktor sowohl für val als auch für T innerhalb von self ausgeführt werden, aber da diese auf die gleichen Daten zeigen, würde dies führen zu einem doppelten frei.

Wenn wir die Bits nicht kopiert hätten, könnten Sie nicht sicher auf das val in "Dinge geschehen" zugreifen, was von geringem Nutzen wäre.

Die by-value-Lösung funktioniert, weil der Compiler verfolgen kann, wer den Destruktor aufrufen soll: die Funktion selbst. Sobald Sie in der Funktion sind, weiß der Compiler, welche spezifischen Zeilen den Wert freigeben müssen und ruft sie im Falle einer Panik richtig auf.

Die Clone oder Default -Lösung funktioniert, weil Sie den Wert nie aus der ursprünglichen Enumeration verschieben. Stattdessen können Sie die ursprüngliche Enumeration durch einen Dummy-Wert ersetzen und das Original übernehmen (mit Default ) oder den gesamten ursprünglichen Wert duplizieren (mit Clone ).

Der replace_with RFC (# 1736) schlug vor, eine Methode hinzuzufügen, die dies ermöglichen würde arbeiten, während Sie sicherstellen, dass die richtige Speichersemantik aufrechterhalten wurde, aber dieser RFC wurde nicht akzeptiert.

    
Shepmaster 15.06.2017 15:23
quelle

Tags und Links