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
:
Es ist möglich mit zusätzlichen Grenzen ( Default
, oder Clone
):
Als Alternative für diesen speziellen Fall könnten Sie in eine Struktur mit einem T
und einer einfachen Enumeration 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%ist es möglich, Varianten im Wert einer änderbaren Referenz zu wechseln
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.