Benutzer-Werkzeuge

Webseiten-Werkzeuge


lua

Lua ist interpretiert und verfügt über ein REPL.
Ende von Statements/Instruktionen wird automatisch erkannt, es können also mehrere auf einer Zeile stehen ohne Trennzeichen oder Zeilenumbruch.

Allgemein

  • am Verbeitetsten ist Lua 5.1
  • alle Versionen nach 5.1 → 5.2, 5.3, 5.4 sind jeweils nicht abwärtskompatibel
    • z.B erzeugt … in einer Funktionsdeklaration in 5.1 eine Tabelle arg, in 5.4 mus … an eine Tabelle übergeben werden um eine Tabelle zu bekommen
    • in 5.1 gibt es eine Funktion unpack zum entpacken von Tabellen, in 5.4 ist unpack eine Methode von table → table.unpack()

Keywords/Onboard-Funktionen

Variablen

  • müssen nicht definiert werden
    • alle Variablen existieren, haben ggf. den Wert nil
  • dynamisch typisiert
  • Bezeichner dürfen nicht mit einer Ziffer beginnen
  • Bezeichner sollten nicht mit einem _ beginnen, da diese Variablen ggf. von lua selbst genutzt werden
  • Variablen können folgende Typen annehmen (der Typ muss nicht deklariert werden)
    • string
      • immutable, wie in Python
        • ein String kann also nicht geändert werden, es kann nur ein neuer erstellt werden
      • kann dynamisch in number umgewandelt werden
        • bei Vergleichen allerdings nicht
      • tonumber(variable) wandelt explizit in number um
      • können beliebige Binärdaten beinhalten
    • number
      • ist float, es gibt kein int
      • wird dynamisch in strings umgewandelt
        • bei Vergleichen allerdings nicht
      • tostring(variable) wandelt es explizit in string um
    • nil
      • Variable hat keinen Wert → None in Python
    • function
      • Funktionen können Variablen zugewiesen werden
  • bei Vergleichen sind false und nil false
    • leere Zeichenketten und 0 sind hingegen true
  • mehrere Variablen können in einem Statement zugewiesen werden
    • werden mehr Variablen als Werte zugewiesen wird nil zugewiesen
    • werden mehr Werte als Variablen angegeben, werden die Werte ohne Meldung verworfen

a, g, f = 1, 3

  • a = 1
  • g = 3
  • f = nil
    • da weniger Werte als Variablen angegeben

Scopes/local

  • Variablen sind per default global
  • lokale Variablen → local variablename = assignment
    • wobei assignment nicht an der Stelle erfoglen muss → dann ist der Wert nil
  • lokale Variablen sind innerhalb eines Chunks (Datei) oder einer Struktur gültig
    • if, loops usw.
  • lokale Variablen können überall im Code deklariert werden
  • auf lokale Variablen kann schneller zugegriffen werden als auf globale

a=6
do
    local a=1
    print(a)
end
print(a)

  • do kann man nutzen wenn man den Scope einschränken will, aber keinen „natürlichen (durch ein if oder eine Schleife) definierten Block hat

Kommentare

  • --

    leitet einen einzeiligen Kommentar ein

  • --[[Sometext--]]

    ist ein mehrzeiliger Kommentar

dofile

Importiert alles aus einer Datei in den lokalen Namespace.

dofile("somefile.lua)

Anschließend können die Funktionen in somefile.lua benutzt werden als wären sie in der lokalen Datei.
Im Prinzip wie wenn man in Python import x from y macht.

function

Definiert eine Funktion

function somename(parameter1, parameter2)
   somecode
end

Funktionen:

  • beginnen mit function
  • und enden mit end

Tables

  • Key-Value-Maps
  • ersetzen Arrays/Lists, Hashmaps/Dicts
  • Keys können klassische Indexes (Zahlen) oder ein beliebiger anderer Datentyp sein, auch durcheinander
    • zu beachten ist allerdings das „1“ und 1 nicht der gleiche Index sind → das eine ist ein String, das andere eine Zahl
  • Tables haben keine vordefinierte Anzahl von Einträgen (wie Arrays), sondern können beliebig verlängert/verkürzt werden
    • es werden keine Werte gespeichert, sondern Referenzen auf die eigentlichen Variablen
    • so wie Lists in Python
  • Zugriff per Index oder in Objektnotation
  • Einträge die nicht vorhanden sind liefern nil zurück

a={}  --Erstellt leere Table
print(a[5]) --Gibt nil zurück, da der Key nicht existiert
a.x=6 --Setzt den Index "x" auf 6
print(a["x"]) --Ergibt 6

  • Variablennamen speichern Referenzen auf Tabellen, nicht aber die Tabelle selbst
    • im Gegensatz zu anderen Datentypen, wo tatsächlich der Wert gespeichert wird
    • tables sind Objekte, keine primitiven Datentypen und werden per Reference gespeichert

a="Hallo"
b=a --b hat jetzt auch den Wert "Hallo"
a="Anders"
print(b) --das gibt "Hallo" zurück, da der Wert von a an b kopiert wurde, nicht die Referenz
c={}
c.x=6
d=c --d und c verweisen jetzt auf die gleiche table als Referenz, nicht als Wert
d.x=8
print(c.x) --das gibt 8 zurück, da c und d auf die gleiche table verweisen, nicht auf den gleichen Wert

  • die Funktion ipairs erlaubt for-Schleifen zu bauen die key und value zurückliefern
    • ähnlich .items() in Python für dicts

for key, value in ipairs(mytable) do
  print(key, value)
end

Instanzieren

a={2,3,x=6}
print(a[1])
print(a["x"])

  • hier wird eine gemischte Table erstellt, die ersten beiden Werte können über einen klassischen Index (1-x) angesprochen werden, der 3. Wert ist per named Index erreichbar („x“), so wie in einem dict/hashmap.
  • das erste print gibt 2 zurück, es wird per index 1 zugegriffen
    • die Indexierung beginnt bei 1, nicht bei 0
    • es wird hier auf die Table wie auf eine normale Liste zugegriffen
  • das zweite print gibt 6 zurück, es wird per index „x“ zugegriffen

Iterieren

Funktioniert über Funktionen.

  • pairs() iteriert über alle Einträge einer Table und liefert den Key (Index) und den jeweiligen Wert zurück
    • gibt es einen expliziten Key (wie bei Hashmaps/Dicts) dann wird dieser zurückgegeben
    • gibt es keinen expliziten Key (wie bei Lists, arrays) wird der Index zurückgegeben
  • ipairs() iteriert über alle Einträge mit numerischem Index und gibt Index und Wert zurück
    • Werte die einen expliziten Index/Key haben (wie bei einer Hashmap) werden nicht zurückgegeben

a={6,8,'bla'='blub', 99}
for key, value in pairs(a) do
    print(key, value)
end

for key, value in ipairs(a) do
    print(key, value)
end

  • erste Schleife gibt aus:
    • 1 6
    • 2 8
    • bla blub
    • 99
  • zweite Schleife gibt aus:
    • 1 6
    • 2 8
    • 3 99
    • der Key und Wert für 'bla' werden übersprungen, der Index ist fortlaufend → 'bla' wird nicht mitgezählt

Operators

Arithmetische Operatoren

  • die üblichen
  • also *, -, +, /

Vergleichsoperatoren

  • < und >
  • ⇐ und >=
  • == - Gleichheit zweier Werte
    • außer bei tables, da müssen beide Variablen auf die gleiche table im Speicher verweisen, es wird nicht der Inhalt geprüft
  • ~= → ungleich

Logische Operatoren

  • nil und false werden beide als false gesehen in logischen Ausdrücken, alles andere als true
  • and - A und B müssen Wahr sein
    • wobei der erste Teil zurückgeben wird wenn er False ergibt
      • also nil and 5 → ergibt nil (nicht false wie man denken könnte)
    • wenn der erste Teil True ergibt wird der zweite Teil zurückgegeben
      • 5 and nil → ergibt nil
      • 5 and 6 → ergibt 6
    • oben stehendes Verhalten ist auch in python so
      • man sieht es nur meist nicht weil man „if whatever“ schreibt und if auf true oder false prüft, auch wenn das was vom Vergleich kam nicht der Wert true oder false war, sondern irgendetwas, es wird nur implizit konvertiert
  • or - Einfaches Or → entweder A oder B muss wahr sein
    • es wird der erste Teil zurückgegeben wenn dieser Wahr ist
      • 5 or 6 → 5 → da 5 wahr
    • ansonsten der zweite Teil
      • nil or 6 → 6 → da der erste Teil nicht wahr ist
      • nil or false → false → da der erste Teil nicht wahr ist
    • oben stehendes Verhalten ist auch in python so
      • man sieht es nur meist nicht weil man „if whatever“ schreibt und if auf true oder false prüft, auch wenn das was vom Vergleich kam nicht der Wert true oder false war, sondern irgendetwas, es wird nur implizit konvertiert
  • Verkettungen sind möglich

a and b or c

String-Verkettung

"bla" .. "blub"
a .. "Blub"

“..„ ist der Verkettungsoperator

if-then-elif-else

if a > b then
    print("A is bigger than B")
elif a < b then
    print("A is smaller than B)
else
    print("A is equal to B or something else ;)")
end

while

i=0
while i<5 do
    print(i)
    i = i + 1
end

repeat-until

i=0
repeat
    print(i)
    i = i + 1
until 

numerische for-Schleife

for i=0, 5, 1 do
    print(i)
end

Führt die Schleife beginnend bei 0 bis 5 in Schritten von 1 aus.

Abstrakt sieht es so aus:

for Variable=Startwert, Stop-Wert, Schritt-Länge do
   Code
end

  • Startwert = erster Wert mit dem die Schleife durchlaufen wird
  • Stop-Wert = der letzte Wert mit dem die Schleife durchlaufen wird
  • Schritt-Länge = Um wie viel die Variable bei jedem Schleifendurchlauf erhöht (oder wenn es eine negative Zahl ist) reduziert wird
    • dieser Parameter kann weggelassen werden, dann wird 1 angenommen
  • die loop-Variable kann innerhalb der Schleife nicht geändert werden (ähnlich Python) und ist automatisch eine lokale Variable (existiert nur innerhalb der Schleife)

Generische for-Schleife

  • bezieht Werte aus einem Iterator

a = {"a","b","c","d"}
for i, v in ipairs(a) do
    print(v)
end

  • i bekommt den Index übergeben
  • v den Wert
  • ipairs ist der Iterator
  • a ist die Tabelle über die iteriert wird

Abstrakt:

for Variablen in Iteratoren do
    Code
end

  • Variablen sind die Variablen die bei jedem Durchlauf der Schleife aus dem Iterator besetzt werden
  • Iterator ist ein Iterator der bei jedem Schleifendurchlauf einen neuen Wert (oder mehrere) zurückgibt

break

  • Bricht aus einer Schleife aus

return

  • Bricht aus einer Funktion aus
  • gibt am Ende einer Funktion Werte an den Aufrufer zurück
    • sollen am Ende einer Funktion keine Werte zurückgeben werden braucht kein return angegeben werden

Funktionen

  • Keyword function
  • Parameter sind lokale Variablen
  • Parameter die beim Aufruf nicht übergeben werden, bekommen nil als Wert
  • Parameter die zu viel übergeben werden werden ohne Fehler verworfen
  • Funktionen sind First-Class-Values
    • sie können also wie strings, int usw. Variablen zugewiesen werden
      • technisch gesehen function <Name> weißt den Code der Variable <Name> zu
  • Funktionen müssen mit Funktionsname() aufgerufen werden
    • die Klammern müssen also zwingend angegeben werden
    • Ausnahme es gibt nur einen Parameter der ein literal String ist oder eine table

function myfunction(param1, param2)
      somecode
end

myfunction("a")

  • param2 wurde in obigem Beispiel beim Aufruf der Funktion nicht übergeben und hätte in der Funktion den Wert nil

Rückgabewerte

  • Funktionen können mehr als 1 Return-Value haben
  • sind mehr Variablen als Rückgabewerte vorhanden, wird mit nil aufgefüllt
  • Default-Rückgabewert = nil

function somefunction()
    return "return1", "return2"
end

somefunction()
a = somefunction()
b, c = somefunction()
d, e, f = somefunction()

Variable Anzahl Paramater

  • per “…„ kann angegeben werden das eine unbestimmte Menge Parameter übergeben werden kann
    • entspricht Pythons *args
  • die Werte befinden sich anschließend in der Tabelle arg

function my(param1, ...)
    print(param1)
    print(unpack(arg))
end

my(1,2,3,4,5)

  • gibt 1 und auf einer neuen Zeile 2,3,4.5 aus
  • unpack entpackt eine Tabelle (wie * in Python)
  • arg ist die Tabelle die die zusätzlichen Parameter enthält

Named Arguments:

  • gibt es nicht
  • kann durch tables (man übergibt eine Table) simuliert werden

Anonyme Funktionen/Lambda

  • man kann einfach keinen Namen angeben
  • der Name nach „function“ ist nur die Zuweisung an eine Variable

function dosomething(f, parameter)
    f(parameter)
end

dosomething(function (string) print(string) end, "hello")

  • dosomething erwartet in diesem Beispiel als ersten Parameter f und als zweiten Parameter einen Parameter den es der Funktion übergibt
  • 'function (string) print(string) end' übergibt eine anonyme Funktion (ohne Namen) beim Funktionsaufruf
  • letztendlich wird die anonyme Funktion aufgerufen und gibt „hello“ zurück

Closure

  • Funktionen in anderen Funktionen haben Zugriff auf die Variablen der sie umgebenden Funktion
  • der Zugriff und die Werte bleiben bestehen, auch wenn der Scope der sie umgebenden Funktion nicht mehr existiert
    • im Prinzip bekommt die Unterfunktion eine Kopie der Variablen der sie umgebenden Funkion
    • im Prinzip kann man es vergleichen mit einem Objekt, dessen Methode Zugang zu den Funktionen eben des Objektes hat

function outer(base)
    local result = base * 5
    inner = function()
        print(result)
        end
    return inner
end

bla = outer(6)
bla()

  • gibt 30 aus
  • inner wird zurückgegeben, hat aber (noch) Zugriff auf die Variablen seiner (nicht mehr existierenden) Eltern-Funktion outer

Begriffe/Konzepte

Begriff Beschreibung
ChunkEin Satz von Instruktionen die nacheinander ausgeführt werden (in einem Schwung). Das kann eine einzelne Zeile (bis man Enter drückt) im REPL (interaktive Konsole) sein oder eine ganze Datei.
lua.txt · Zuletzt geändert: 2024/05/26 17:30 von root