Benutzer-Werkzeuge

Webseiten-Werkzeuge


scripting:tutorials:level1:variable_scope

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Nächste Überarbeitung
Vorherige Überarbeitung
scripting:tutorials:level1:variable_scope [2023/05/22 15:18] – angelegt fritz_98scripting:tutorials:level1:variable_scope [2024/05/13 13:11] (aktuell) fritz_98
Zeile 37: Zeile 37:
  
 -- Bis hier her ist "Information" nicht verändert worden. Der Hinweis zur Schatztruhe besteht also noch. -- Bis hier her ist "Information" nicht verändert worden. Der Hinweis zur Schatztruhe besteht also noch.
--- Bit folgendem Aufruf allerdings verändert sich der "Information"-String. Es wird aus dem Aufruf der+-- Mit folgendem Aufruf allerdings verändert sich der "Information"-String. Es wird aus dem Aufruf der
 -- Funktion nicht ersichtlich, dass er das tut, was diese Art Fehler schwer zu finden macht -- Funktion nicht ersichtlich, dass er das tut, was diese Art Fehler schwer zu finden macht
 DifficultyString = GetDifficultyString(2) DifficultyString = GetDifficultyString(2)
Zeile 69: Zeile 69:
 [[ https://www.lua.org/demo.html ]] [[ https://www.lua.org/demo.html ]]
  
-Um dabei bei der Ausgabe ein Ergebnis zu sehen, kann man ''print'' verwenden. Will man beispielsweise die Variable ''Information'' ansehen, kann man+Um dabei bei der Ausgabe ein Ergebnis zu sehen, kann man die Funktion ''print'' verwenden. Will man beispielsweise die Variable ''Information'' ansehen, kann man
 <code lua> <code lua>
 print(Information) print(Information)
Zeile 78: Zeile 78:
  
 ===== Blöcke ===== ===== Blöcke =====
 +
 +Ein Block sind eine oder mehrere zusammengehörige Instruktionen. "Zusammengehörig" bedeutet dabei nicht einfach nur, dass sie zusammenstehen, sondern dass sie zusammen ausgeführt werden. Bei einer Verzweigung beispielsweise bilden der Fall, dass die Bedingung erfüllt ist und der Fall dass sie nicht erfüllt ist, jeweils einen Block.
 +
 +<code lua>
 +if Text == "Ma-i-a hi" then
 +    -- Anfang Block 1
 +    print(Text)
 +    print("Ma-i-a hu")
 +    print("Ma-i-a ho")
 +    print("Ma-i-a ha-ha")
 +    -- Ende Block 1
 +elseif Text == "nu mă" then
 +    -- Anfang Block 2
 +    print(Text)
 +    print("nu mă iei")
 +    print("Nu mă, nu mă iei")
 +    print("nu mă, nu mă, nu mă iei")
 +    -- Ende Block 2
 +end
 +-- Der Befehl print hat in Siedler 5 keine Funktion
 +-- Der Code muss also in der lua demo, die oben verlinkt ist, ausgeführt werden
 +-- Alternativ können alle print-Aufrufe auch durch Message ersetzt werden. Dann wird Text im Spiel angezeigt
 +</code>
 +
 +Blöcke können Problemlos auch ineinander geschachtelt werden, wie die Minimumssuche [[ scripting:tutorials:level1:branches | hier ]] gut zeigt.
 +
 +Im Allgemeinen ist ein Block immer zwischen einem Schlüsselwort wie ''then'', ''else'', ''function'' (im nächsten Kapitel auch ''do'') und dem ''end'', das einen Block abschließt. Würde man den Code oben in eine Funktion setzen, würde die gesamte Verzweigung einen äußeren Block bilden:
 +
 +<code lua>
 +function DragosteaDinTei(_Text)
 +    -- Anfang äußerer Block
 +    if _Text == "Ma-i-a hi" then
 +        -- Anfang innerer Block 1
 +        print(_Text)
 +        print("Ma-i-a hu")
 +        print("Ma-i-a ho")
 +        print("Ma-i-a ha-ha")
 +        -- Ende innerer Block 1
 +    elseif _Text == "nu mă" then
 +        -- Anfang innerer Block 2
 +        print(_Text)
 +        print("nu mă iei")
 +        print("Nu mă, nu mă iei")
 +        print("nu mă, nu mă, nu mă iei")
 +        -- Ende innerer Block 2
 +    end
 +    -- Ende äußerer Block
 +end
 +</code>
  
 ---- ----
  
 ===== Lokale Variablen ===== ===== Lokale Variablen =====
 +
 +In lokalen Variablen können Zwischenergebnisse und andere Daten, die später verworfen werden sollen, gespeichert werden. Eine lokale Variable wird mit dem vorangehenden Schlüsselwort ''local'' deklariert:
 +<code lua>
 +local Result = 42
 +</code>
 +
 +Eine lokale Variable ist nur im gleichen Block gültig, in dem sie definiert wurde. Dies schließt alle darin eingeschlossenen Unterblöcke mit ein.
 +
 +<code lua>
 +function TestScope()
 +    local Variable = 5
 +    print(Variable)
 +    if Variable == 5 then
 +        Variable = 42
 +    end
 +    print(Variable)
 +end
 +
 +TestScope() -- zeigt zuerst 5, dann 42 an
 +</code>
 +
 +**Achtung**: Wenn du nach der Definition einer lokalen Variable diese überschreiben willst, darf **nicht** das Schlüsselwort ''local'' verwendet werden. Jedes ''local'' führt eine **neue** lokale Variable im aktuellen Block ein:
 +<code lua>
 +function TestScope()
 +    local Variable = 5
 +    if Variable == 5 then
 +        local Variable = 42
 +        print(Variable) -- hier wird wie erwartet 42 angezeigt
 +    end
 +    print(Variable) 
 +    -- hier wird 5 angezeigt, da die lokale Variable aus dem if-Block nicht mehr existiert
 +    -- (if-Block ist zuende)
 +end
 +
 +TestScope() -- zeigt zuerst 42, dann 5 an
 +</code>
 +
 +**Achtung**: Zudem musst du darauf achten, dass eine lokale Variable, die du benutzen willst, wirklich im genau dem Block definiert ist, in dem du sie benutzen willst. Zwei Beispiele:
 +<code lua>
 +function TestScope()
 +    -- mit 'do' kann man ohne zusätzliche Bedingungen einen neuen Block starten
 +    do
 +        local Variable = 5
 +    end
 +    print(Variable)
 +end
 +
 +TestScope() --zeigt 'nil' an
 +</code>
 +In diesem Beispiel wird nicht 5, sondern ''nil'' ausgegeben, da die Variable zum Zeitpunkt des ''print''-Befehls nicht mehr existiert. Der Block, in dem sie definiert wurde, ist mit ''end'' zu Ende, sodass man sich danach nicht mehr darauf beziehen kann. 
 +
 +Anderes Beispiel:
 +<code lua>
 +function TestScope()
 +    do
 +        local Variable = 5
 +    end
 +    Variable = 42
 +    print(Variable)
 +end
 +
 +TestScope() -- zeigt 42 an. Allerdings wurde eine globale Variable erschaffen/überschrieben
 +</code>
 +Hier wird zwar die erwartete 42 ausgegeben, allerdings wurde eine **globale** Variable erschaffen. Da wie im vorigen Beispiel die lokale Variable unterhalb von ''end'' nicht mehr existiert, kann man sich dort nicht mehr darauf beziehen. Ohne ''local'' entsteht demnach eine globale Variable bzw. eine bereits existierende globale Variable wird überschrieben.
 +
 +Um diesen Abschnitt abzuschließen, wollen wir unser Beispiel oben "bereinigen". Dazu definieren wir wieder die Funktion ''GetDifficultyString'', allerdings unter Zuhilfenahme einer lokalen Variable:
 +<code lua>
 +function GetDifficultyString(_Difficulty)
 +    local Information = "Du hast die "
 +    if _Difficulty == 1 then
 +        Information = Information.."leichte "
 +    elseif _Difficulty == 2 then
 +        Information = Information.."mittlere "
 +    elseif _Difficulty == 3 then
 +        Information = Information.."schwierige "
 +    end
 +    Information = Information.."Variante gewählt!"
 +    return Information
 +end
 +</code>
 +
 +Dies wird mit keiner globalen Variable mehr kollidieren. Lokale Variablen haben in dem Block, in dem sie definiert wurden, immer "Vorrang" gegenüber gleichnamigen globalen Variablen. Wenn also wie im Beispiel oben ein globaler String ''Information'' existiert, wird innerhalb der Funktion trotzdem die korrekte lokale Variable benutzt und anschließend wieder verworfen. Damit der generierte String nicht verloren geht, kann er in einer globalen Variable gespeichert werden:
 +<code lua>
 +DifficultyString = GetDifficultyString(2)
 +</code>
 +
 +Es ist sehr sinnvoll, sich die Zeit zu nehmen, zu überlegen, wo genau in diesem Beispiel welche Variablen existieren.
  
 ---- ----
Zeile 87: Zeile 223:
 ===== Verwendungszwecke ===== ===== Verwendungszwecke =====
  
-TODO: Beispielhaft Use Cases für lokale und globale Variablen (Anzahl Schatztruhen vs Zwischenergebnisse). +Zum Schluss wollen wir noch einige Beispiele geben, für welche Zwecke globale und lokale Variablen sinnvoll sind. 
-TODO: Funktionen sind normalerweise immer global + 
-TODO: Parameter in Funktionen sind immer lokal+^ Verwendungszweck ^ Global oder lokal? ^ 
 +| Zähle die Anzahl der vom Spieler gefundenen Schatzkisten | Global, da man jederzeit wissen möchte, wie viele Kisten gefunden wurden | 
 +Zwischenergebnisse in einer Funktion | Lokal, da lediglich das Ergebnis zählt und mit einem ''return'' an eine Ergebnisvariable gegeben werden kann | 
 +| Funktionen | Funktionen sind in der Regel immer global | 
 +Parameter | Parameter, die einer Funktion übergeben werden, sind zwangsweise **immer** lokal und können deshalb nur innerhalb der Funktion benutzt werden | 
 + 
 +---- 
 + 
 +Um mit wenig Schreibarbeit große Rechenvorschriften aufzuschreiben, werden im nächsten Kapitel Schleifen eingeführt.
  
 +[[ scripting:tutorials:level1:functions_blocks | Voriges Kapitel: Funktionen ]]\\
 +[[ scripting:tutorials:level1:loops | Nächstes Kapitel: Schleifen ]]\\
 +[[ scripting:tutorials:level1:variable_scope | Zurück nach oben ]]
scripting/tutorials/level1/variable_scope.1684768733.txt.gz · Zuletzt geändert: 2023/05/22 15:18 von fritz_98