2012-11-16 4 views
6

Was ist der Zweck der Übergabe von Argumenten an lua_resume und lua_yield?Lua: lua_resume und lua_yield Argument Zwecke

Ich verstehe, dass beim ersten Aufruf von lua_resume die Argumente an die Lua-Funktion übergeben werden, die gerade fortgesetzt wird. Das macht Sinn. Ich würde jedoch erwarten, dass alle nachfolgenden Aufrufe von lua_resume die Argumente in der Coroutine-Funktion "aktualisieren" würden. Das ist jedoch nicht der Fall.

Was ist der Zweck der Übergabe von Argumenten an lua_resume, damit lua_yield zurückkehren kann? Kann die Lua-Funktion, die unter der Coroutine läuft, auf die Argumente zugreifen, die von lua_resume übergeben werden?

Antwort

10

Was Nicol sagte. Sie können immer noch die Werte aus dem ersten resume Anruf erhalten, wenn Sie wollen:

do 
    local firstcall 
    function willyield(a) 
    firstcall = a 
    while a do 
     print(a, firstcall) 
     a = coroutine.yield() 
    end 
    end 
end 

local coro = coroutine.create(willyield) 
coroutine.resume(coro, 1) 
coroutine.resume(coro, 10) 
coroutine.resume(coro, 100) 
coroutine.resume(coro) 

1 1 
10 1 
100 1 
+0

Ich glaube, das beantwortet die Frage nicht.Im OP ging es um die/C-API/Funktionen lua_resume() und lua_yield(), die eine andere Semantik als die Standardbibliothek 'coroutine.resume()' usw. haben. Zum Beispiel benötigt lua_resume drei Argumente - zwei davon sind lua_State ...) – BadZen

+0

Ich denke, es beantwortet die Frage nach dem Zweck, Parameter zu übergeben und bietet ein Beispiel, das leicht zu versuchen ist, einen Lua-Interpreter zu haben. In der Tat, sagte OP in seinem Kommentar unter Nicols Antwort. Sie können immer Ihre eigene Antwort geben, wenn Sie denken, Sie haben eine bessere Antwort. –

+0

Es gibt einen großen Unterschied zwischen dem Coroutinobjekt in libs (das zum Beispiel einen lua_State einkapselt) und der C-API. Ich habe keine bessere Antwort, also habe ich eine andere Frage gestellt, die speziell nach der C-API fragt. Nichols Antwort und Ihre hier sprechen beide von dem Koroutinenbibliotheksobjekt. Es gibt etwa 100 Codezeilen, die das in Bezug auf die lua_ * API implementieren. Es ist nicht offensichtlich, und die Dokumentation enthält wenig Details. – BadZen

5

Lua kann den ursprünglichen Argumenten nicht magisch neue Werte geben. Sie sind möglicherweise nicht mehr auf dem Stapel, abhängig von den Optimierungen. Außerdem gibt es keinen Hinweis darauf, wo der Code war, als er nachgab, sodass er diese Argumente möglicherweise nicht mehr sehen kann. Wenn zum Beispiel die Coroutine eine Funktion aufgerufen hat, kann diese neue Funktion die Argumente, die in die alte übergeben wurden, nicht sehen.

coroutine.yield() gibt die an den Aufruf resume übergebenen Argumente zurück, die die Coroutine fortsetzen, sodass die Site des Yield-Aufrufs Parameter so verarbeiten kann, wie sie es wünschen. Es ermöglicht dem Code, der die Wiederaufnahme durchführt, mit dem spezifischen Code zu kommunizieren, der das Nachgeben bewirkt. yield() übergibt seine Argumente als Rückgabewerte von resume, und resume übergibt seine Argumente als Rückgabewerte an yield. Dies schafft einen Kommunikationsweg.

Sie können das nicht anders machen. Sicherlich nicht, indem Sie Argumente ändern, die möglicherweise von der yield-Site aus nicht sichtbar sind. Es ist einfach, elegant und macht Sinn.

Außerdem wird es als äußerst unhöflich angesehen, auf jemandes Werte zu stoßen. Vor allem eine Funktion bereits in Betrieb. Denken Sie daran: Argumente sind nur lokale Variablen, die mit Werten gefüllt sind. Der Benutzer sollte nicht erwarten, dass sich der Inhalt dieser Variablen ändert, wenn er sie nicht selbst ändert. Sie sind schließlich local Variablen. Sie können nur lokal geändert werden; daher der Name.

+0

Dank gedruckt wird! Um zu verdeutlichen, können die lokalen Werte nach dem Start einer Coroutine nicht mehr von außen verändert werden. Ich würde annehmen, dass ich dann über globale Variablen mit den Interna der Coroutine kommunizieren müsste? Zum Beispiel könnte ich eine Anzahl "naher Objekte" in einem Spiel zählen, wo die Coroutine wissen muss, wie viele andere Objekte in einer Entfernung sind. Um dies zu tun, müsste ich ein Global haben, um die Anzahl der Objekte in der Nähe zu speichern. Ich hatte gehofft, ich könnte die Coroutine unmittelbar vor meiner Wiederaufnahme bewerten, um zu vermeiden, den Namensraum mit Globalen zu umklammern. – RandyGaul

+0

Die Werte können geändert werden; Sie müssen das Ergebnis des Aufrufs coroutine.yield() nur der gleichen Variablen zuweisen, die Sie ursprünglich als Parameter übergeben haben. Sehen Sie sich zum Beispiel meine Antwort an. –

+0

@RandyGaul: "* sobald eine Coroutine gestartet wird, können die lokalen Werte nicht extern geändert werden *" 'lokale' Variablen können nicht extern geändert werden * Periode *; Koroutinen sind nicht besonders. Wenn Sie diese Zahl weitergeben möchten, übergeben Sie sie als Parameter an 'resume' und sammeln Sie sie als Rückgabewert von' yield'. Wie gesagt, das ist die Kommunikationsschnittstelle, die Sie haben. –