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.
Gibt es eine bessere Methode, diesen Fehler zu umgehen und / oder andere Funktionen, die ich über Kanäle senden soll?
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
Tags und Links rust channel function-pointers