2016-07-21 46 views
4

Ich habe zwei Funktionen, die sich gelegentlich gegenseitig aufrufen, und sie sind lokal für ein Modul, das sie verwendet, um eine andere Funktion zu erstellen. Das Modul ist etwas ähnlich zu diesem Stück Code:Lokale Funktionen, die sich gegenseitig anrufen

local function iseven(n) 
    if n == 1 then 
     return false 
    else 
     return isodd(n - 1) 
    end 
end 

local function isodd(n) 
    if n == 1 then 
     return true 
    else 
     return iseven(n - 1) 
    end 
end 

local evenOrOdd = function(n) 
    return iseven(n) and "Even" or "Odd" 
end 

return evenOrOdd 

Das Problem ist, wenn evenOrOdd aus einer anderen Datei aufruft ich den Fehler attempt to call global 'isodd' (a nil value).

Ich bemerkte, dass dies nicht passiert, wenn ich iseven auf global festlegen, aber ich möchte sie lokal zu meinem Modul behalten.

Ich habe sogar versucht, eine Dummy-Funktionsdeklaration (local function isodd() end) vor der Zeile, wo iseven deklariert ist. Ich habe auch versucht, nur local isodd anstelle der Dummy-Funktionsdeklaration einzufügen, aber auf beide Arten funktioniert es nicht und ich bekomme verschiedene Arten von Fehlern.

Ich weiß, das liegt daran, dass Lua Verschlüsse hat und wenn iseven erklärt fängt sie den tatsächlichen Wert des isodd, die entweder nil oder die Dummy-Funktion ist, und es nach der Änderung zählt nicht, aber gibt es eine Möglichkeit, um Bypass Dies?

+2

Beispiel für Vorwärtsdeklaration in Lua: 'local f; lokale Funktion g() return f() end; Funktion f() zurück g() Ende' –

+0

@Egor Skriptunoff oh richtig. Wie ich in der Frage gesagt habe, habe ich es versucht. Aber es scheint, dass ich vergessen habe, 'local' vor' function isodd (n) 'zu löschen und ich habe den' Versuch, den Wert 'isodd' (ein Nullwert) 'error aufzurufen. Vielen Dank. – user6245072

+0

Die Fehlermeldung für den Code, den Sie angegeben haben, sollte 'versuchen, global 'isodd' (ein Nullwert) aufzurufen', was erklären sollte, was passiert ist. – lhf

Antwort

-1

Bessere Kontrolle für num%2 - Rest der Division

+1

Es war nur ein Beispiel, um zu zeigen, wie meine Funktionen funktionieren. Sie sind wirklich zu lang, um sie hier zu kopieren und die Frage kann trotzdem beantwortet werden (siehe in den Kommentaren). – user6245072

5

Das Problem ist, dass der Aufruf von isodd in iseven eine variable globalen verwendet, nicht die lokale später definiert ein.

Sie mit der Vorwärts Erklärungen, wie @Egor vorgeschlagen:

local iseven, isodd 

function iseven(n) 
... 
end 

function isodd(n) 
... 
end 

... 
2

Ein anderer Weg Vergangenheit dieses Problem zu umgehen ist Tabellen zu verwenden. Einfache lokale Variablen sind wahrscheinlich effizienter, aber bei Tabellen müssen Sie die Deklarationen nicht verwalten.

local T = {} 

local function evenOrOdd(n) 
    return T.iseven(n) and "Even" or "Odd" 
end 

function T.iseven(n) 
    -- code 
end 

Der Kern ist, dass, da die Tabelle ganz oben definiert ist, alles unter ihm Zugang zu ihm hat, und Sie können es dynamisch seinen Inhalt ändern. Wenn evenOrOdd aufgerufen wird, sollte T.iseven bereits dann definiert sein, obwohl es nicht definiert wurde, wenn evenOrOdd definiert wurde.