Looking for lua Keywords? Try Ask4Keywords

LuaErste Schritte mit Lua


Bemerkungen

Lua-Logo

Lua ist eine minimalistische, leichte und einbettbare Skriptsprache. Sie wird von einem Team am PUC-Rio , der Päpstlichen Katholischen Universität von Rio de Janeiro in Brasilien, entworfen, implementiert und gewartet. Die Mailingliste ist offen, um mitzumachen.

Übliche Anwendungsfälle für Lua umfassen das Erstellen von Videospielen, das Erweitern von Anwendungen mit Plug-Ins und Konfigurationen, das Einschließen einiger übergeordneter Geschäftslogiken oder das Einbetten in Geräte wie Fernseher, Autos usw.

Für Hochleistungsaufgaben steht eine unabhängige Implementierung unter Verwendung des Just-in-Time-Compilers zur Verfügung, der als LuaJIT bezeichnet wird .

Versionen

Ausführung Anmerkungen Veröffentlichungsdatum
1,0 Erstveröffentlichung, nicht öffentliche Veröffentlichung. 1993-07-28
1.1 Erste öffentliche Veröffentlichung. Konferenzpapier beschreibt es. 1994-07-08
2.1 Ab Lua 2.1 wurde Lua für alle Zwecke einschließlich kommerzieller Zwecke frei verfügbar. Zeitschriftenpapier beschreibt es. 1995-02-07
2.2 Lange Zeichenfolgen, die Debug-Schnittstelle, bessere Stack-Tracebacks 1995-11-28
2.4 Externer luac Compiler 1996-05-14
2,5 Pattern-Matching- und Vararg-Funktionen. 1996-11-19
3,0 Einführung der auxlib, einer Bibliothek zum Schreiben von Lua-Bibliotheken 1997-07-01
3.1 Anonyme Funktionen und Funktionsschließungen über "Upvalues". 1998-07-11
3.2 Debugbibliothek und neue Tabellenfunktionen 1999-07-08
3.2.2 2000-02-22
4,0 Mehrere Zustände, "for" -Anweisungen, API-Überarbeitung. 2000-11-06
4.0.1 2002-07-04
5,0 Coroutines, Metatables, vollständiger lexikalischer Umfang, Tail Calls, Booleans wechseln zur MIT-Lizenz. 2003-04-11
5.0.3 2006-06-26
5.1 Überarbeitung des Modulsystems, inkrementeller Speicherbereiniger, Metatables für alle Typen, luaconf.h Überarbeitung, vollständig wiedereintrittsfähiger Parser, verschiedene Argumente 2006-02-21
5.1.5 2012-02-17
5.2 Notmüllsammler, goto, Finalizer für Tische. 2011-12-16
5.2.4 2015-03-07
5.3 Grundlegende UTF-8-Unterstützung, bitweise Operationen, 32/64-Bit-Ganzzahlen. 2015-01-12
5.3.4 Letzte Version. 2017-01-12

Bemerkungen

Einzeilige Kommentare in Lua beginnen mit -- und werden bis zum Zeilenende fortgesetzt:

-- this is single line comment
-- need another line
-- huh?
 

Block-Kommentare beginnen mit --[[ und enden mit ]] :

--[[
    This is block comment.
    So, it can go on...
    and on...
    and on....
]]
 

Block-Kommentare verwenden den gleichen Stil von Trennzeichen wie lange Zeichenfolgen. Zwischen den Klammern können beliebig viele Gleichheitszeichen eingefügt werden, um einen Kommentar abzugrenzen:

--[=[
    This is also a block comment
    We can include "]]" inside this comment
--]=]

--[==[
    This is also a block comment
    We can include "]=]" inside this comment
--]==]
 

Ein ordentlicher Trick, um Codeabschnitte auszukommentieren, besteht darin, ihn mit --[[ und --]] :

--[[
    print'Lua is lovely'
--]]
 

Zum Reaktivieren des Blocks fügen Sie einfach ein - an die Kommentarsequenz an:

---[[
    print'Lua is lovely'
--]]
 

Auf diese Weise wird die Sequenz -- in der ersten Zeile -- wie in der letzten Zeile ein einzeiliger Kommentar gestartet, und die print wird nicht auskommentiert.

Um noch einen Schritt weiter zu gehen, können zwei Codeblöcke so eingerichtet werden, dass der zweite Block nicht auskommentiert wird, und umgekehrt:

---[[
  print 'Lua is love'
--[=[]]
  print 'Lua is life'
--]=]
 

Um den zweiten Chunk zu aktivieren, während der erste Chunk deaktiviert wird, löschen Sie das führende - in der ersten Zeile:

--[[
  print 'Lua is love'
--[=[]]
  print 'Lua is life'
--]=]
 

Lua-Programme ausführen

Normalerweise wird Lua mit zwei Binärdateien ausgeliefert:

  • lua - Standalone - Interpreter und interaktive Shell
  • luac - Bytecode - Compiler

bottles_of_mate.lua wir an, wir haben ein Beispielprogramm ( bottles_of_mate.lua ) wie bottles_of_mate.lua :

local string = require "string"    

function bottle_take(bottles_available)

    local count_str = "%d bottles of mate on the wall."
    local take_str = "Take one down, pass it around, " .. count_str
    local end_str = "Oh noes, " .. count_str
    local buy_str = "Get some from the store, " .. count_str
    local bottles_left = 0

    if bottles_available > 0 then
         print(string.format(count_str, bottles_available))
         bottles_left = bottles_available - 1
         print(string.format(take_str, bottles_left))
    else
        print(string.format(end_str, bottles_available))
        bottles_left = 99
        print(string.format(buy_str, bottles_left))
    end

    return bottles_left
end

local bottle_count = 99

while true do
    bottle_count = bottle_take(bottle_count)
end
 

Das Programm selbst kann ausgeführt werden, indem Sie Folgendes in Ihrer Shell ausführen:

$ lua bottles_of_mate.lua
 

Die Ausgabe sollte in der Endlosschleife so aussehen:

Get some from the store, 99 bottles of mate on the wall.
99 bottles of mate on the wall.
Take one down, pass it around, 98 bottles of mate on the wall.
98 bottles of mate on the wall.
Take one down, pass it around, 97 bottles of mate on the wall.
97 bottles of mate on the wall.
...
...
3 bottles of mate on the wall.
Take one down, pass it around, 2 bottles of mate on the wall.
2 bottles of mate on the wall.
Take one down, pass it around, 1 bottles of mate on the wall.
1 bottles of mate on the wall.
Take one down, pass it around, 0 bottles of mate on the wall.
Oh noes, 0 bottles of mate on the wall.
Get some from the store, 99 bottles of mate on the wall.
99 bottles of mate on the wall.
Take one down, pass it around, 98 bottles of mate on the wall.
...
 

Sie können das Programm in Luas Bytecode kompilieren, indem Sie Folgendes in Ihrer Shell ausführen:

$ luac bottles_of_mate.lua -o bottles_of_mate.luac
 

Eine Bytecode-Auflistung ist auch verfügbar, indem Sie Folgendes ausführen:

$ luac -l bottles_of_mate.lua


main <./bottles.lua:0,0> (13 instructions, 52 bytes at 0x101d530)
0+ params, 4 slots, 0 upvalues, 2 locals, 4 constants, 1 function
    1    [1]    GETGLOBAL    0 -1    ; require
    2    [1]    LOADK        1 -2    ; "string"
    3    [1]    CALL         0 2 2
    4    [22]    CLOSURE      1 0    ; 0x101d710
    5    [22]    MOVE         0 0
    6    [3]    SETGLOBAL    1 -3    ; bottle_take
    7    [24]    LOADK        1 -4    ; 99
    8    [27]    GETGLOBAL    2 -3    ; bottle_take
    9    [27]    MOVE         3 1
    10    [27]    CALL         2 2 2
    11    [27]    MOVE         1 2
    12    [27]    JMP          -5    ; to 8
    13    [28]    RETURN       0 1

function <./bottles.lua:3,22> (46 instructions, 184 bytes at 0x101d710)
1 param, 10 slots, 1 upvalue, 6 locals, 9 constants, 0 functions
    1    [5]    LOADK        1 -1    ; "%d bottles of mate on the wall."
    2    [6]    LOADK        2 -2    ; "Take one down, pass it around, "
    3    [6]    MOVE         3 1
    4    [6]    CONCAT       2 2 3
    5    [7]    LOADK        3 -3    ; "Oh noes, "
    6    [7]    MOVE         4 1
    7    [7]    CONCAT       3 3 4
    8    [8]    LOADK        4 -4    ; "Get some from the store, "
    9    [8]    MOVE         5 1
    10    [8]    CONCAT       4 4 5
    11    [9]    LOADK        5 -5    ; 0
    12    [11]    EQ           1 0 -5    ; - 0
    13    [11]    JMP          16    ; to 30
    14    [12]    GETGLOBAL    6 -6    ; print
    15    [12]    GETUPVAL     7 0    ; string
    16    [12]    GETTABLE     7 7 -7    ; "format"
    17    [12]    MOVE         8 1
    18    [12]    MOVE         9 0
    19    [12]    CALL         7 3 0
    20    [12]    CALL         6 0 1
    21    [13]    SUB          5 0 -8    ; - 1
    22    [14]    GETGLOBAL    6 -6    ; print
    23    [14]    GETUPVAL     7 0    ; string
    24    [14]    GETTABLE     7 7 -7    ; "format"
    25    [14]    MOVE         8 2
    26    [14]    MOVE         9 5
    27    [14]    CALL         7 3 0
    28    [14]    CALL         6 0 1
    29    [14]    JMP          15    ; to 45
    30    [16]    GETGLOBAL    6 -6    ; print
    31    [16]    GETUPVAL     7 0    ; string
    32    [16]    GETTABLE     7 7 -7    ; "format"
    33    [16]    MOVE         8 3
    34    [16]    MOVE         9 0
    35    [16]    CALL         7 3 0
    36    [16]    CALL         6 0 1
    37    [17]    LOADK        5 -9    ; 99
    38    [18]    GETGLOBAL    6 -6    ; print
    39    [18]    GETUPVAL     7 0    ; string
    40    [18]    GETTABLE     7 7 -7    ; "format"
    41    [18]    MOVE         8 4
    42    [18]    MOVE         9 5
    43    [18]    CALL         7 3 0
    44    [18]    CALL         6 0 1
    45    [21]    RETURN       5 2
    46    [22]    RETURN       0 1
 

Fertig machen

Variablen

var = 50 -- a global variable
print(var) --> 50
do
  local var = 100 -- a local variable
  print(var) --> 100
end
print(var) --> 50
-- The global var (50) still exists 
-- The local var (100) has gone out of scope and can't be accessed any longer.
 

Typen

num = 20 -- a number
num = 20.001 -- still a number
str = "zaldrizes buzdari iksos daor" -- a string
tab = {1, 2, 3} -- a table (these have their own category)
bool = true -- a boolean value
bool = false -- the only other boolean value
print(type(num)) --> 'number'
print(type(str)) --> 'string'
print(type(bool)) --> 'boolean'
type(type(num)) --> 'string'

-- Functions are a type too, and first-class values in Lua.
print(type(print)) --> prints 'function'
old_print = print
print = function (x) old_print "I'm ignoring the param you passed me!" end
old_print(type(print)) --> Still prints 'function' since it's still a function.
-- But we've (unhelpfully) redefined the behavior of print.
print("Hello, world!") --> prints "I'm ignoring the param you passed me!"
 

Der besondere Typ nil

Ein anderer Typ in Lua ist nil . Der einzige Wert in dem nil - Typ ist nil . nil existiert, um sich von allen anderen Werten in Lua zu unterscheiden. Es ist eine Art wertloser Wert.

print(foo) -- This prints nil since there's nothing stored in the variable 'foo'.
foo = 20
print(foo) -- Now this prints 20 since we've assigned 'foo' a value of 20.

-- We can also use `nil` to undefine a variable
foo = nil -- Here we set 'foo' to nil so that it can be garbage-collected.

if nil then print "nil" end --> (prints nothing)
-- Only false and nil are considered false; every other value is true.
if 0 then print "0" end --> 0
if "" then print "Empty string!" --> Empty string!
 

Ausdrücke

a = 3
b = a + 20 a = 2 print(b, a) -- hard to read, can also be written as
b = a + 20; a = 2; print(a, b) -- easier to read, ; are optional though
true and true --> returns true
true and 20 --> 20
false and 20 --> false
false or 20 --> 20
true or 20 --> true
tab or {}
  --> returns tab if it is defined
  --> returns {} if tab is undefined
  -- This is useful when we don't know if a variable exists
tab = tab or {} -- tab stays unchanged if it exists; tab becomes {} if it was previously nil.

a, b = 20, 30 -- this also works
a, b = b, a -- switches values
 

Funktionen definieren

function name(parameter)
    return parameter
end
print(name(20)) --> 20
-- see function category for more information
name = function(parameter) return parameter end -- Same as above
 

Booleaner

Nur false und nil werden als false ausgewertet, alles andere, einschließlich 0 und die leere Zeichenfolge als true.

Müllsammlung

tab = {"lots", "of", "data"}
tab = nil; collectgarbage()
-- tab does no longer exist, and doesn't take up memory anymore.
 

Tische

tab1 = {"a", "b", "c"}
tab2 = tab1
tab2[1] = "d"
print(tab1[1]) --> 'd' -- table values only store references.
--> assigning tables does not copy its content, only the reference.

tab2 = nil; collectgarbage()
print(tab1) --> (prints table address) -- tab1 still exists; it didn't get garbage-collected.

tab1 = nil; collectgarbage()
-- No more references. Now it should actually be gone from memory.
 

Dies sind die Grundlagen, aber es gibt einen Abschnitt mit Tabellen mit mehr Informationen.

Bedingungen

if (condition) then
    -- do something
elseif (other_condition) then
    -- do something else
else
    -- do something
end
 

für Schleifen

Es gibt zwei Arten von for Schleifen in Lua: eine numerische for Schleife und eine generische for Schleife.

  • Eine numerische for Schleife hat die folgende Form:

    for a=1, 10, 2 do -- for a starting at 1, ending at 10, in steps of 2
      print(a) --> 1, 3, 5, 7, 9
    end
     

    Der dritte Ausdruck in einer numerischen for Schleife ist der Schritt, um den die Schleife erhöht wird. Dies macht es einfach, umgekehrte Schleifen auszuführen:

     for a=10, 1, -1 do
       print(a) --> 10, 9, 8, 7, 6, etc.
     end
     

    Wenn der Schrittausdruck ausgelassen wird, geht Lua von einem Standardschritt von 1 aus.

     for a=1, 10 do
       print(a) --> 1, 2, 3, 4, 5, etc.
     end
     

    Beachten Sie auch, dass die Schleifenvariable lokal für die for Schleife ist. Es wird nicht existieren, nachdem die Schleife beendet ist.

  • Generic for Schleifen durchläuft alle Werte, die eine Iteratorfunktion zurückgibt:

    for key, value in pairs({"some", "table"}) do
      print(key, value)
      --> 1 some
      --> 2 table
    end
     

    Lua bietet mehrere integrierte Iteratoren (z. B. pairs , ipairs pairs ), und Benutzer können ihre eigenen benutzerdefinierten Iteratoren definieren, die auch mit generischen for Schleifen verwendet werden können.

Blöcke machen

local a = 10
do
    print(a) --> 10
    local a = 20
    print(a) --> 20
end
print(a) --> 10
 

Hallo Welt

Dies ist Hallo Weltcode:

print("Hello World!")
 

Wie es funktioniert? Es ist einfach! Lua führt die print() Funktion aus und verwendet als Argument die Zeichenfolge "Hello World" .

Installation

Binaries

Lua-Binaries werden von den meisten GNU / Linux-Distributionen als Paket bereitgestellt.

Unter Debian, Ubuntu und ihren Derivaten kann es beispielsweise durch Ausführen dieses Befehls erworben werden:

sudo apt-get install lua50
 
sudo apt-get install lua51
 
sudo apt-get install lua52
 

Es gibt einige halboffizielle Builds für Windows, MacOS und einige andere bei SourceForge gehostete Betriebssysteme.

Apple-Nutzer können Lua auch einfach mit Homebrew installieren:

brew install lua
 

(Derzeit hat Homebrew 5.2.4, für 5.3 siehe Homebrew / Versionen .)

Quelle

Quelle ist auf der offiziellen Seite verfügbar. Die Beschaffung von Quellen und der Build selbst sollten trivial sein. Auf Linux-Systemen sollte Folgendes ausreichen:

$ wget http://lua.org/ftp/lua-5.3.3.tar.gz
$ echo "a0341bc3d1415b814cc738b2ec01ae56045d64ef ./lua-5.3.3.tar.gz" | sha1sum -c -
$ tar -xvf ./lua-5.3.3.tar.gz
$ make -C ./lua-5.3.3/ linux
 

Im obigen Beispiel laden wir im Grunde ein Quell- tarball von der offiziellen Website herunter, überprüfen dessen Prüfsumme und extrahieren und führen make . (Überprüfen Sie die Checksumme auf der offiziellen Seite .)

Hinweis: Sie müssen das gewünschte Build-Ziel angeben. In dem Beispiel haben wir linux angegeben. Andere verfügbare Build - Ziele umfassen solaris , aix , bsd , freebsd , macosx , mingw etc. Check out doc/readme.html , die in der Quelle enthalten ist, für weitere Details. ( Die neueste Version der README finden Sie auch online .)

Module

Standardbibliotheken sind auf Grundelemente beschränkt:

  • coroutine - Coroutine Management-Funktionalität
  • debug - debug Hooks und Werkzeuge
  • io - Grund IO Primitiven
  • package - Modul - Verwaltungsfunktion
  • string String- und Lua-spezifische Pattern-Matching-Funktionalität
  • table für den Umgang mit essentiellen, aber komplexen Lua-Typ-Tabellen
  • os - grundlegende Betriebssystemvorgänge
  • utf8 - grundlegende UTF-8-Primitive (seit Lua 5.3)

Alle diese Bibliotheken können für einen bestimmten Build deaktiviert oder zur Laufzeit geladen werden.

Lua-Bibliotheken und Infrastruktur von Drittanbietern zum Verteilen von Modulen sind spärlich, verbessern sich jedoch. Projekte wie LuaRocks , Lua Toolbox und LuaDist verbessern die Situation. Viele Informationen und Vorschläge finden Sie im älteren Lua-Wiki. Beachten Sie jedoch, dass einige dieser Informationen ziemlich alt und veraltet sind.

Einige knifflige Dinge

Manchmal verhält sich Lua nicht so, wie man nach dem Lesen der Dokumentation denkt. Einige dieser Fälle sind:

Nil und Nichts sind nicht dasselbe (COMMON PITFALL!)

Wie erwartet, table.insert(my_table, 20) der Tabelle den Wert 20 und table.insert(my_table, 5, 20) den Wert 20 an der fünften Position hinzu. Was macht table.insert(my_table, 5, nil) ? Man könnte erwarten, dass er nil als überhaupt kein Argument behandelt und den Wert 5 am Ende der Tabelle einfügt, aber tatsächlich fügt er den Wert nil an der fünften Position der Tabelle hinzu. Wann ist das ein Problem?

(function(tab, value, position)
    table.insert(tab, position or value, position and value)
end)({}, 20)
-- This ends up calling table.insert({}, 20, nil)
-- and this doesn't do what it should (insert 20 at the end)
 

Ähnliches passiert bei tostring() :

print (tostring(nil)) -- this prints "nil"
table.insert({}, 20) -- this returns nothing
-- (not nil, but actually nothing (yes, I know, in lua those two SHOULD
-- be the same thing, but they aren't))

-- wrong:
print (tostring( table.insert({}, 20) ))
-- throws error because nothing ~= nil

--right:
local _tmp = table.insert({}, 20) -- after this _tmp contains nil
print(tostring(_tmp)) -- prints "nil" because suddenly nothing == nil
 

Dies kann auch zu Fehlern bei der Verwendung von Drittanbietercode führen. Wenn beispielsweise in der Dokumentation einiger Funktionszustände "Donuts bei Erfolg zurückgegeben wird, sonst nichts" zurückgegeben wird, könnte die Implementierung in etwa so aussehen

function func(lucky)
    if lucky then
        return "donuts"
    end
end
 

Diese Implementierung mag auf den ersten Blick vernünftig erscheinen. Es gibt Donuts zurück, wenn es erforderlich ist, und wenn Sie result = func(false) eingeben, enthält result den Wert nil .

Wenn Sie jedoch print(tostring(func(false))) schreiben würden, würde lua einen Fehler stdin:1: bad argument #1 to 'tostring' (value expected) aussieht stdin:1: bad argument #1 to 'tostring' (value expected)

Warum das? tostring bekommt eindeutig ein Argument, obwohl es gleich nil . Falsch. tostring(func(false)) nichts zurückgibt, ist tostring(func(false)) dasselbe wie tostring() und NICHT das gleiche wie tostring(nil) .

Fehler, die "Wert erwartet" sagen, sind ein starkes Indiz dafür, dass dies die Ursache des Problems sein kann.

Lücken in Arrays lassen

Dies ist eine große Falle, wenn Sie mit Lua noch nicht vertraut sind, und es gibt viele Informationen in der Tabellenkategorie