Lua Tutorial
Iniziare con Lua
Ricerca…
Osservazioni
Lua è un linguaggio di scripting minimalista, leggero e integrabile. È stato progettato, implementato e gestito da un team della PUC-Rio , la Pontificia Università Cattolica di Rio de Janeiro in Brasile. La mailing list è aperta per essere coinvolta.
Casi di utilizzo comuni per Lua includono la creazione di script di videogiochi, l'estensione di applicazioni con plug-in e config, l'involuzione di alcune logiche di business di alto livello o semplicemente l'incorporamento in dispositivi come TV, automobili, ecc.
Per attività ad alte prestazioni esiste un'implementazione indipendente che utilizza il compilatore just-in-time disponibile chiamato LuaJIT .
Versioni
Versione | Gli appunti | Data di rilascio |
---|---|---|
1.0 | Versione iniziale, non pubblica. | 1993/07/28 |
1.1 | Prima versione pubblica. Documento della Conferenza che lo descrive. | 1994/07/08 |
2.1 | A partire da Lua 2.1, Lua è diventata disponibile gratuitamente per tutti gli scopi, compresi gli usi commerciali. Documento ufficiale che lo descrive. | 1995/02/07 |
2.2 | Stringhe lunghe, l'interfaccia di debug, migliori stackback di stack | 1995/11/28 |
2.4 | Compilatore luac esterno | 1996/05/14 |
2.5 | Funzioni di corrispondenza del modello e vararg. | 1996/11/19 |
3.0 | Introdotto auxlib, una libreria per aiutare a scrivere le librerie Lua | 1997/07/01 |
3.1 | Funzioni anonime e chiusure di funzioni tramite "upvalues". | 1998/07/11 |
3.2 | Libreria di debug e nuove funzioni di tabella | 1999/07/08 |
3.2.2 | 2000/02/22 | |
4.0 | Stati multipli, istruzioni "for", aggiornamento API. | 2000/11/06 |
4.0.1 | 2002-07-04 | |
5.0 | Coroutine, metatables, scoping lessicale completo, chiamate di coda, booleans passano alla licenza MIT. | 2003/04/11 |
5.0.3 | 2006-06-26 | |
5.1 | Revamp del sistema di moduli, garbage collector incrementale, metatables per tutti i tipi, luaconf.h revamp, parser completamente rientranti, argomenti variadici. | 2006-02-21 |
5.1.5 | 2012-02-17 | |
5.2 | Garbage collector di emergenza, goto, finalizzatori per tavoli. | 2011-12-16 |
5.2.4 | 2015/03/07 | |
5.3 | Supporto UTF-8 di base, operazioni bit a bit, interi 32/64 bit. | 2015/01/12 |
5.3.4 | Ultima versione. | 2017/01/12 |
Installazione
Binari
I binari Lua sono forniti dalla maggior parte delle distribuzioni GNU / Linux come un pacchetto.
Ad esempio, su Debian, Ubuntu e le loro derivate può essere acquisito eseguendo questo:
sudo apt-get install lua50
sudo apt-get install lua51
sudo apt-get install lua52
Ci sono alcune build semi-ufficiali fornite per Windows, MacOS e alcuni altri sistemi operativi ospitati su SourceForge .
Gli utenti Apple possono anche installare facilmente Lua usando Homebrew :
brew install lua
(Attualmente Homebrew ha 5.2.4, per 5.3 vedere Homebrew / versioni .)
fonte
La fonte è disponibile nella pagina ufficiale . L'acquisizione di fonti e la costruzione di se stessa dovrebbero essere banali. Sui sistemi Linux dovrebbe essere sufficiente quanto segue:
$ 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
Nell'esempio sopra stiamo fondamentalmente scaricando un tarball
sorgente dal sito ufficiale, verificandone il checksum ed estraendo ed eseguendo make
. (Controlla il checksum nella pagina ufficiale ).
Nota: è necessario specificare quale target di build si desidera. Nell'esempio, abbiamo specificato linux
. Altri obiettivi di costruzione disponibili includono solaris
, aix
, bsd
, freebsd
, macosx
, mingw
, ecc. Per ulteriori dettagli, mingw
doc/readme.html
, che è incluso nella fonte. (Puoi anche trovare l'ultima versione del README online .)
moduli
Le librerie standard sono limitate alle primitive:
-
coroutine
- funzionalità di gestione di coroutine -
debug
- ganci e strumenti di debug -
io
- I / O primitivi di base -
package
- funzionalità di gestione dei moduli -
string
e funzionalità di corrispondenza specifica del modello Lua -
table
- primitive per trattare un tipo di Lua essenziale ma complesso - tabelle -
os
- operazioni di base del sistema operativo -
utf8
- primitive UTF-8 di base (dal Lua 5.3)
Tutte queste librerie possono essere disabilitate per una build specifica o caricate in fase di esecuzione.
Librerie e infrastrutture Lua di terze parti per la distribuzione di moduli sono scarse, ma migliorano. Progetti come LuaRocks , Lua Toolbox e LuaDist stanno migliorando la situazione. Molte informazioni e molti suggerimenti possono essere trovati sul vecchio Lua Wiki , ma sappiate che alcune di queste informazioni sono piuttosto vecchie e obsolete.
Commenti
Commenti a riga singola in Lua iniziano con --
e continuano fino alla fine della riga:
-- this is single line comment
-- need another line
-- huh?
Blocca i commenti che iniziano con --[[
e termina con ]]
:
--[[
This is block comment.
So, it can go on...
and on...
and on....
]]
I commenti di blocco utilizzano lo stesso stile di delimitatore di stringhe lunghe; qualsiasi numero di segni di uguale può essere aggiunto tra parentesi per delimitare un commento:
--[=[
This is also a block comment
We can include "]]" inside this comment
--]=]
--[==[
This is also a block comment
We can include "]=]" inside this comment
--]==]
Un trucco per commentare blocchi di codice è circondarlo con --[[
e --]]
:
--[[
print'Lua is lovely'
--]]
Per riattivare il blocco, aggiungi semplicemente una -
alla sequenza di apertura del commento:
---[[
print'Lua is lovely'
--]]
In questo modo, la sequenza --
nella prima riga inizia un commento a riga singola, proprio come l'ultima riga, e l'istruzione di print
non è commentata.
Facendo un ulteriore passo avanti, due blocchi di codice possono essere impostati in modo tale che se il primo blocco viene commentato, il secondo non lo sarà, e viceversa:
---[[
print 'Lua is love'
--[=[]]
print 'Lua is life'
--]=]
Per attivare il secondo blocco mentre disabiliti il primo blocco, elimina l'iniziale -
nella prima riga:
--[[
print 'Lua is love'
--[=[]]
print 'Lua is life'
--]=]
Esecuzione di programmi Lua
Di solito, Lua viene spedito con due file binari:
-
lua
- interprete indipendente e shell interattiva - compilatore
luac
-bytecode
Diciamo che abbiamo un programma di esempio ( bottles_of_mate.lua
) come questo:
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
Il programma stesso può essere eseguito eseguendo in seguito sulla tua shell:
$ lua bottles_of_mate.lua
L'output dovrebbe assomigliare a questo, correndo nel ciclo infinito:
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.
...
Puoi compilare il programma nel bytecode di Lua eseguendo il seguente comando sulla tua shell:
$ luac bottles_of_mate.lua -o bottles_of_mate.luac
Anche l'elenco bytecode è disponibile eseguendo quanto segue:
$ 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
Iniziare
variabili
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.
tipi
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!"
Il tipo speciale nil
Un altro tipo in Lua è nil
. L'unico valore nel nil
tipo è nil
. nil
esiste per essere diverso da tutti gli altri valori in Lua. È un tipo di valore non valore.
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!
espressioni
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
Definizione di funzioni
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
booleani
Solo false
e nil
valutano come false, tutto il resto, incluso 0
e la stringa vuota vengono valutate come vere.
raccolta dei rifiuti
tab = {"lots", "of", "data"}
tab = nil; collectgarbage()
-- tab does no longer exist, and doesn't take up memory anymore.
tavoli
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.
Queste sono le basi, ma c'è una sezione sulle tabelle con maggiori informazioni.
condizioni
if (condition) then
-- do something
elseif (other_condition) then
-- do something else
else
-- do something
end
per loops
Ci sono due tipi di loop for
in Lua: un ciclo numerico for
loop e un ciclo for
generico.
Un ciclo numerico
for
ha la seguente forma: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
La terza espressione in un ciclo numerico
for
è il passo in base al quale il ciclo aumenterà. Ciò facilita i cicli di inversione:for a=10, 1, -1 do print(a) --> 10, 9, 8, 7, 6, etc. end
Se l'espressione del passo viene omessa, Lua assume un passo predefinito di 1.
for a=1, 10 do print(a) --> 1, 2, 3, 4, 5, etc. end
Si noti inoltre che la variabile loop è locale al ciclo
for
. Non esisterà dopo che il ciclo è finito.
Generico
for
cicli lavoro attraverso tutti i valori che una funzione iteratore restituisce:for key, value in pairs({"some", "table"}) do print(key, value) --> 1 some --> 2 table end
Lua fornisce diverse costruita nel iteratori (ad esempio,
pairs
,ipairs
), e gli utenti possono definire i propri iteratori ordinazione pure da utilizzare con genericofor
cicli.
fare blocchi
local a = 10
do
print(a) --> 10
local a = 20
print(a) --> 20
end
print(a) --> 10
Alcune cose complicate
A volte Lua non si comporta come si potrebbe pensare dopo aver letto la documentazione. Alcuni di questi casi sono:
Nil e Nothing non sono gli stessi (COMUNE PITFALL!)
Come previsto, table.insert(my_table, 20)
aggiunge il valore 20
alla tabella e table.insert(my_table, 5, 20)
aggiunge il valore 20 alla 5a posizione. Cosa fanno invece table.insert(my_table, 5, nil)
? Ci si potrebbe aspettare che trattino nil
come nessun argomento, e inserisca il valore 5
alla fine della tabella, ma in realtà aggiunge il valore nil
alla 5a posizione della tabella. Quando è un problema?
(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)
Una cosa simile accade con il 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
Ciò potrebbe anche causare errori durante l'utilizzo di codice di terze parti. Se, ad esempio, la documentazione di alcuni stati di funzione "restituisce ciambelle se fortunati, altrimenti nulla", l'implementazione potrebbe sembrare un po 'come questa
function func(lucky)
if lucky then
return "donuts"
end
end
questa implementazione potrebbe sembrare ragionevole all'inizio; restituisce le ciambelle quando deve, e quando si digita result = func(false)
result conterrà il valore nil
.
Tuttavia, se si scrivesse la print(tostring(func(false)))
lua genererebbe un errore simile a questo stdin:1: bad argument #1 to 'tostring' (value expected)
Perché? tostring
ottiene chiaramente una discussione, anche se è nil
. Sbagliato. func non restituisce nulla, quindi tostring(func(false))
è lo stesso di tostring()
e NOT lo stesso di tostring(nil)
.
Errori che dicono "valore atteso" sono una forte indicazione che questa potrebbe essere la fonte del problema.
Lasciare spazi vuoti negli array
Questa è una trappola enorme se sei nuovo a lua e ci sono molte informazioni nella categoria delle tabelle
Ciao mondo
Questo è ciao codice mondiale:
print("Hello World!")
Come funziona? È semplice! Lua esegue la funzione print()
e usa la stringa "Hello World"
come argomento.