Kann nicht aus der gefangenen äußeren Variablen in einer 'Fn'-Schließung herauskommen

8

Ich versuche herauszufinden, wie man eine Funktion über einen Kanal sendet und wie man zusätzliches Klonen vermeidet, um die Funktion am anderen Ende auszuführen. Wenn ich den zusätzlichen Klonvorgang innerhalb des Abschlusses entferne, erhalte ich den folgenden Fehler:

%Vor%

Wenn ich die Tatsache ignoriere, dass dieser Code absolut nichts tut und eine globale veränderbare statische Sender<T> verwendet, stellt er dar, was ich zu erreichen versuche, während ich die richtigen Compiler-Fehler gebe. Dieser Code ist nicht zum Ausführen gedacht , nur kompiliert.

%Vor%

Gibt es eine bessere Methode, diesen Fehler zu umgehen und / oder andere Funktionen, die ich über Kanäle senden soll?

    
nathansizemore 11.11.2015, 23:56
quelle

1 Antwort

11

Das Problem mit Fn() ist, dass Sie es mehrmals aufrufen können. Wenn Sie einen erfassten Wert verlassen, ist dieser Wert beim nächsten Aufruf nicht mehr verfügbar. Du brauchst ein FnOnce() , um sicher zu stellen, dass der Aufruf des Closures sich auch aus ihm heraus bewegt, also ist es weg und kann nicht wieder aufgerufen werden.

Es gibt keine Möglichkeit, ein Arc<Mutex<(FnOnce() + Send + Sync + 'static)>> zu haben. Dies würde wiederum erfordern, dass Sie statisch garantieren, dass, nachdem Sie die Funktion aufgerufen haben, niemand anders sie erneut aufrufen kann. Was nicht möglich ist, da ein anderer Arc auf dein FnOnce zeigen kann. Was Sie tun können, ist es boxen und senden Sie es als Box<FnOnce() + Send + Sync + 'static> . Es gibt nur einen Besitzer von Box .

Das Problem mit FnOnce() ist, dass Sie es nicht wirklich aufrufen können, solange es sich in der Box befindet, denn dazu müssten Sie es aus der Box herausziehen und aufrufen. Aber wir wissen nicht wie groß es ist, also können wir es nicht aus dem Box entfernen. In Zukunft könnten Box<FnOnce()> closures direkt verwendbar sein.

"Zum Glück" ist dieses Problem häufiger aufgetreten, also gibt es FnBox . Leider erfordert dies jede Nacht zur Arbeit. Auch konnte ich nicht herausfinden, wie man die in den Dokumenten beschriebene Funktionsaufrufsyntax verwendet, aber Sie können call_box für Box<FnBox()> manuell aufrufen. Probieren Sie es im Spielplatz

aus     
oli_obk - ker 12.11.2015, 09:50
quelle

Tags und Links