Zum Inhalt springen
Lua Anfänger 25 min

if, for & while

Kontrollfluss in Lua: if-elseif-else, numerische for-Schleifen, generic for mit pairs/ipairs, while und repeat.

Aktualisiert:
Inhaltsverzeichnis

Kontrollstrukturen in Lua

Lua’s Syntax ist ausdrucksstark und verzichtet auf Klammern, do...end und then markieren die Blocks.

if / elseif / else

local alter = 18

if alter >= 18 then
  print("Volljaehrig")
elseif alter >= 16 then
  print("Fast volljaehrig")
else
  print("Zu jung")
end

Merke:

  • then nach der Bedingung ist Pflicht
  • elseif (ein Wort!)
  • end schliesst das Konstrukt
  • Keine Klammern um die Bedingung noetig

Kurzform mit and/or

Lua hat keinen ternaeren Operator. Stattdessen nutzt man das and/or-Idiom:

local text = alter >= 18 and "volljaehrig" or "minderjaehrig"

Achtung: Funktioniert nur, wenn der “then”-Wert niemals falsy ist.

Logische Operatoren

-- and
if aktiv and alter >= 18 then ... end

-- or
if premium or alter >= 21 then ... end

-- not
if not aktiv then ... end

Sie nutzen Kurzschluss-Evaluation, und - wie wir sahen - liefern Werte:

local name = input or "Anonym"    -- Default

Kein switch

Lua hat keinen switch oder case. Stattdessen:

Via if/elseif

if tag == "Montag" then
  print("Wochenstart")
elseif tag == "Dienstag" or tag == "Mittwoch" or tag == "Donnerstag" then
  print("Mitte der Woche")
else
  print("Anderer Tag")
end

Via Table-Lookup

Eleganter bei vielen Faellen:

local messages = {
  Montag = "Wochenstart",
  Freitag = "Bald Wochenende",
}

print(messages[tag] or "Anderer Tag")

Numerische for-Schleife

for i = 1, 5 do
  print(i)    -- 1, 2, 3, 4, 5
end

Mit Schrittweite:

for i = 1, 10, 2 do
  print(i)    -- 1, 3, 5, 7, 9
end

for i = 10, 1, -1 do
  print(i)    -- 10, 9, ..., 1
end

Die Grenzen sind inklusiv.

Generic for mit Iteratoren

Der andere Alltags-Loop - mit ipairs oder pairs:

ipairs - Array iterieren

local namen = {"Max", "Anna", "Leo"}

for i, name in ipairs(namen) do
  print(i, name)
end
-- 1  Max
-- 2  Anna
-- 3  Leo

ipairs geht nur ueber den Array-Teil (1, 2, 3, …) und stoppt beim ersten nil.

pairs - alle Keys iterieren

local person = { name = "Anna", alter = 28, aktiv = true }

for key, value in pairs(person) do
  print(key, value)
end

Reihenfolge ist nicht garantiert - pairs nutzt die interne Hash-Reihenfolge.

while

local n = 10
while n > 0 do
  print(n)
  n = n - 1
end

Beachte: Lua kennt kein ++ oder -- - immer n = n + 1.

repeat ... until

Lua’s Variante von do-while, aber umgedreht:

local eingabe
repeat
  io.write("> ")
  eingabe = io.read()
until eingabe == "quit"
  • until bedingung - laeuft, bis die Bedingung wahr wird (das Gegenteil von while)
  • Laeuft mindestens einmal

break - aber kein continue

for i, name in ipairs(namen) do
  if name == "Anna" then
    break             -- Schleife verlassen
  end
  print(name)
end

Lua hat klassisch kein continue. Es gibt zwei Workarounds:

if invertieren

for i, n in ipairs(zahlen) do
  if n % 2 == 1 then    -- nur ungerade verarbeiten
    print(n)
  end
end

goto continue (Lua 5.2+)

for i, n in ipairs(zahlen) do
  if n % 2 == 0 then goto continue end
  print(n)
  ::continue::
end

Luau hingegen hat continue - angenehmer.

Funktionen als Iteratoren

Du kannst eigene Iteratoren bauen:

local function reichweite(n)
  local i = 0
  return function()
    i = i + 1
    if i <= n then return i end
  end
end

for x in reichweite(5) do
  print(x)    -- 1, 2, 3, 4, 5
end

Das ist fortgeschritten, zeigt aber, wie flexibel das for-Konstrukt ist.

Kurze Variablen in for

Lua erlaubt dir, im ipairs-Loop nur einen Wert zu holen:

for _, name in ipairs(namen) do    -- Index ignorieren
  print(name)
end

Der _ ist eine Konvention fuer “ignoriertes Ergebnis”.

pcall - Error Handling

Lua nutzt fuer Fehler error() und pcall() (protected call):

local function riskant()
  error("etwas ist kaputt")
end

local ok, err = pcall(riskant)
if not ok then
  print("Fehler:", err)
end

Das ist Lua’s Variante von try/catch. Elegant, aber anders als in anderen Sprachen.

Praktisches Beispiel

local function kategorisiere(alter)
  if alter < 0 then return "ungueltig" end
  if alter < 18 then return "Kind" end
  if alter < 65 then return "Erwachsen" end
  return "Senior"
end

local function verarbeite(namen, alter)
  print("Alle:")
  for _, name in ipairs(namen) do
    print("  " .. name)
  end

  print("\nKategorien:")
  for name, a in pairs(alter) do
    print(string.format("  %s: %s", name, kategorisiere(a)))
  end
end

verarbeite(
  {"Max", "Anna", "Leo"},
  { Max = 34, Anna = 28, Leo = 17 }
)

Zusammenfassung

  • if / elseif / else / end mit then nach Bedingungen
  • Kein eingebauter switch - nutze Table-Lookup oder if-Kaskaden
  • Numeric for for i = start, end, step do ... end
  • Generic for mit ipairs (Array) oder pairs (alle Keys)
  • repeat ... until statt do-while (Bedingung umgekehrt!)
  • break geht, continue braucht Goto-Label
  • pcall fuer Error Handling

Im naechsten Kapitel: Funktionen und Multi-Return-Magie.

Zurück zum Lua Kurs