Verwenden des Rust-Compilers, um zu verhindern, dass eine Methode aufgerufen wird

8

Ich habe einen Code wie diesen:

%Vor%

Es ist wirklich wichtig, dass ich beide dieser Operationen eventuell mache, aber oft vergesse ich, die zweite nach der ersten zu machen. Es verursacht viele Bugs und ich frage mich, ob es einen idiomatischen Rust-Weg gibt, um dieses Problem zu vermeiden. Gibt es eine Möglichkeit, den Rost-Compiler dazu zu bringen, mich wissen zu lassen, wenn ich es vergesse?

Meine Idee war, vielleicht so etwas zu haben:

%Vor%

Gibt es einen besseren Weg, dies zu erreichen?

Eine weitere Idee besteht darin, Drop und panic! zu implementieren, wenn die Struktur gelöscht wird, ohne diese Methode aufgerufen zu haben. Dies ist jedoch nicht so gut, da es sich um eine Laufzeitprüfung handelt und das höchst unerwünscht ist.

Bearbeiten: Ich habe festgestellt, dass mein Beispiel vielleicht zu einfach war. Die involvierte Logik kann ziemlich komplex werden. Zum Beispiel haben wir so etwas:

%Vor%

Beachten Sie, dass die Vorgänge nicht in einer netten, ordnungsgemäß verschachtelten Reihenfolge ausgeführt werden. Wichtig ist nur, dass die umgekehrte Operation immer danach aufgerufen wird. Die Reihenfolge muss manchmal auf eine bestimmte Weise angegeben werden, damit der Code wie erwartet funktioniert.

Wir können sogar so etwas haben:

%Vor%     
Sunjay Varma 04.02.2017, 05:26
quelle

3 Antworten

12

Sie können Phantom-Typen verwenden, um zusätzliche Informationen mitzuführen, die für die Typprüfung verwendet werden können. Eine Einschränkung ist, dass move_left_by und move_right_by ein neues Objekt im Besitz zurückgeben müssen, weil sie den Typ ändern müssen, aber das ist oft kein Problem.

Außerdem wird der Compiler sich beschweren, wenn Sie die Typen in Ihrer Struktur nicht verwenden, also müssen Sie Felder hinzufügen, die sie verwenden. Rust's std liefert PhantomData für diesen Zweck. Werte dieses Typs haben keine Laufzeitkosten.

Es kann ein wenig unhandlich sein, aber Ihre Einschränkung könnte wie folgt codiert werden:

%Vor%

Sie können es wie folgt verwenden:

%Vor%

Und wenn Sie eine der erforderlichen Methoden vermissen,

%Vor%

Dann erhalten Sie einen Kompilierfehler:

%Vor%     
Peter Hall 04.02.2017 13:05
quelle
6

Ich glaube nicht, dass #[must_use] in diesem Fall wirklich das ist, was Sie wollen. Hier sind zwei verschiedene Ansätze zur Lösung Ihres Problems. Der erste Schritt besteht darin, das, was Sie bei einem Abschluss machen müssen, abzuschließen und die direkten Aufrufe wegzuspalten:

%Vor%

Der zweite Ansatz besteht darin, einen Wrappertyp zu erstellen, der die Funktion aufruft, wenn sie gelöscht wird (ähnlich wie Mutex::lock eine MutexGuard erzeugt, die die Mutex freigibt, wenn sie gelöscht wird):

%Vor%     
Erik Vesteraas 04.02.2017 13:02
quelle
1

Ich habe nur die anfängliche Beschreibung angeschaut und wahrscheinlich die Details in der Konversation verpasst, aber eine Möglichkeit, die Aktionen zu erzwingen, besteht darin, das ursprüngliche Objekt zu konsumieren (nach rechts zu gehen) und es durch eines zu ersetzen, das Sie zwingt um sich um denselben Betrag nach links zu bewegen, bevor Sie tun können, was Sie tun wollten, um die Aufgabe zu beenden.

Der neue Typ kann verbieten / erfordern, dass verschiedene Anrufe getätigt werden, bevor ein fertiger Zustand erreicht wird. Zum Beispiel (ungetestet):

%Vor%

An diesem Punkt kann sich foo nicht mehr richtig bewegen, da es von MustGoLeft nicht erlaubt ist, aber es kann sich nach links bewegen oder die Box öffnen. Wenn es sich weit genug nach links bewegt, kehrt es wieder in den Zustand CanGoRight zurück. Aber wenn es die Box öffnet, dann gelten völlig neue Regeln. So oder so müssen Sie mit beiden Möglichkeiten umgehen.

Es wird wahrscheinlich einige Überschneidungen zwischen den Staaten geben, aber sollte leicht genug sein, um zu refaktorieren. Das Hinzufügen eines benutzerdefinierten Merkmals könnte helfen.

Am Ende hört es sich so an, als würdest du eine Art Staatsmaschine bauen. Vielleicht wird Ссылка von Nutzen sein.

    
Tommi Komulainen 08.02.2017 22:19
quelle

Tags und Links