Lua Tutorial
Erste Schritte mit Lua
Suche…
Bemerkungen
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 |
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.
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 generischenfor
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
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
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"
.