Lua Handledning
Komma igång med Lua
Sök…
Anmärkningar
Lua är minimalistiskt, lätt och inbäddbart skriptspråk. Det designas, implementeras och underhålls av ett team vid PUC-Rio , det Pontifical Katolska universitetet i Rio de Janeiro i Brasilien. Postlistan är öppen för att engagera sig.
Vanliga användningsfall för Lua inkluderar skriptvideospel, utvidgning av applikationer med plugins och configs, inslagning av viss affärslogik på hög nivå eller bara inbäddning i enheter som TV: er, bilar etc.
För högpresterande uppgifter finns det oberoende implementering med just-in-time-kompilator tillgänglig LuaJIT .
versioner
Version | anteckningar | Utgivningsdatum |
---|---|---|
1,0 | Inledande, icke-offentlig släpp. | 1993/07/28 |
1,1 | Första public release. Konferensbidrag som beskriver det. | 1994/07/08 |
2,1 | Från och med Lua 2.1 blev Lua fritt tillgängligt för alla ändamål, inklusive kommersiellt bruk. Tidskrift som beskriver det. | 1995/02/07 |
2,2 | Långa strängar, felsökningsgränssnittet, bättre stack tracebacks | 1995/11/28 |
2,4 | Extern luac kompilator | 1996/05/14 |
2,5 | Mönstermatchning och vararg-funktioner. | 1996/11/19 |
3,0 | Introducerade auxlib, ett bibliotek för att hjälpa till att skriva Lua-bibliotek | 1997/07/01 |
3,1 | Anonyma funktioner och funktionsstängningar via "uppvärderingar". | 1998/07/11 |
3,2 | Felsöka bibliotek och nya tabellfunktioner | 1999/07/08 |
3.2.2 | 2000-02-22 | |
4,0 | Flera tillstånd, "för" uttalanden, API-ombyggnad. | 2000-11-06 |
4.0.1 | 2002-07-04 | |
5,0 | Coroutines, metatables, full lexikalsk scoping, svans samtal, booleaner flytta till MIT licens. | 2003-04-11 |
5.0.3 | 2006-06-26 | |
5,1 | Modulsystem ombyggnad, inkrementell sopor samlare, metatabeller för alla typer, luaconf.h uppdatering, helt reentrant parser, variadiska argument. | 2006-02-21 |
5.1.5 | 2012-02-17 | |
5,2 | Nödavfallssamlare, goto, finalizers för bord. | 2011-12-16 |
5.2.4 | 2015/03/07 | |
5,3 | Grundläggande UTF-8-stöd, bitvisa ops, 32 / 64bit-heltal. | 2015/01/12 |
5.3.4 | Senaste versionen. | 2017/01/12 |
Installation
binärer
Lua-binärer tillhandahålls av de flesta GNU / Linux-distributioner som ett paket.
På Debian, Ubuntu och deras derivat kan det till exempel förvärvas genom att utföra detta:
sudo apt-get install lua50
sudo apt-get install lua51
sudo apt-get install lua52
Det finns några semi-officiella builds som tillhandahålls för Windows, MacOS och vissa andra operativsystem värd på SourceForge .
Apple-användare kan också installera Lua enkelt med Homebrew :
brew install lua
(För närvarande har Homebrew 5.2.4, för 5.3 se Homebrew / versioner .)
Källa
Källan finns tillgänglig på den officiella sidan . Förvärv av källor och bygga sig själv bör vara trivialt. På Linux-system bör följande vara tillräckligt:
$ 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
I exemplet ovan laddar vi i princip ned en tarball
från den officiella sajten, verifierar dess kontrollsumma, och tar ut och kör make
. (Kolla in kontrollsumman på den officiella sidan .)
Obs! Du måste ange vilket byggmål du vill ha. I exemplet specificerade vi linux
. Andra tillgängliga byggmål inkluderar solaris
, aix
, bsd
, freebsd
, macosx
, mingw
, etc. Kolla in doc/readme.html
, som ingår i källan, för mer information. (Du kan också hitta den senaste versionen av README online .)
moduler
Standardbibliotek är begränsade till primitiv:
-
coroutine
- coroutinehanteringsfunktionalitet -
debug
- felsökningskrokar och verktyg -
io
- grundläggande IO-primitiva -
package
- modulhanteringsfunktionalitet -
string
- sträng och Lua specifik mönster matchning funktionalitet -
table
- primitiv för att hantera en väsentlig men komplextable
Lua-typ -
os
- grundläggande operativsystem -
utf8
- grundläggande UTF-8-primitiv (sedan Lua 5.3)
Alla dessa bibliotek kan inaktiveras för en specifik byggnad eller laddas vid körning.
Tredjeparts Lua-bibliotek och infrastruktur för distribution av moduler är glesa, men förbättras. Projekt som LuaRocks , Lua Toolbox och LuaDist förbättrar situationen. Mycket information och många förslag finns på den äldre Lua Wiki , men var medveten om att en del av denna information är ganska gammal och inaktuell.
kommentarer
Kommentarer med en rad i Lua börjar med --
och fortsätt till slutet av raden:
-- this is single line comment
-- need another line
-- huh?
Blockera kommentarer börjar med --[[
och slutar med ]]
:
--[[
This is block comment.
So, it can go on...
and on...
and on....
]]
Blockera kommentarer använder samma stil som avgränsare som långa strängar; valfritt antal lika tecken kan läggas till mellan parenteserna för att avgränsa en kommentar:
--[=[
This is also a block comment
We can include "]]" inside this comment
--]=]
--[==[
This is also a block comment
We can include "]=]" inside this comment
--]==]
Ett snyggt trick för att kommentera kodbitar är att omge det med --[[
och --]]
:
--[[
print'Lua is lovely'
--]]
För att återaktivera biten ska du bara lägga till en -
till sekvensen för kommentaröppning:
---[[
print'Lua is lovely'
--]]
På så sätt startar sekvensen --
i den första raden startar en kommentar på en rad, precis som den sista raden, och print
sägs inte ut.
Genom att ta detta ett steg längre kan två kodblock konfigureras på ett sådant sätt att om det första blocket kommenteras kommer det andra inte att vara, och vice versa:
---[[
print 'Lua is love'
--[=[]]
print 'Lua is life'
--]=]
För att aktivera den andra biten medan du inaktiverar den första biten, ta bort ledningen -
på den första raden:
--[[
print 'Lua is love'
--[=[]]
print 'Lua is life'
--]=]
Utför Lua-program
Vanligtvis levereras Lua med två binärer:
-
lua
- fristående tolk och interaktivt skal -
luac
- bytecode kompilator
Låt oss säga att vi har ett bottles_of_mate.lua
( bottles_of_mate.lua
) som detta:
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
Programmet kan köras genom att följa följande på ditt skal:
$ lua bottles_of_mate.lua
Output ska se ut så här och kör i den oändliga slingan:
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.
...
Du kan kompilera programmet till Luas bytekod genom att utföra följande på ditt skal:
$ luac bottles_of_mate.lua -o bottles_of_mate.luac
Även bytecode-lista är tillgänglig genom att utföra följande:
$ 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
Komma igång
variabler
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.
typer
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!"
Den speciella typen nil
En annan typ i Lua är nil
. Det enda värdet i nil
är nil
. nil
existerar för att vara annorlunda från alla andra värden i Lua. Det är ett slags värde utan värde.
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!
uttryck
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
Definiera funktioner
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
booleska
Endast false
och nil
utvärdera som falska, allt annat, inklusive 0
och den tomma strängen utvärderar som sant.
skräp samling
tab = {"lots", "of", "data"}
tab = nil; collectgarbage()
-- tab does no longer exist, and doesn't take up memory anymore.
tabeller
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.
Det här är grunderna, men det finns ett avsnitt om tabeller med mer information.
betingelser
if (condition) then
-- do something
elseif (other_condition) then
-- do something else
else
-- do something
end
för öglor
Det finns två typer av for
loop i Lua: ett numeriskt for
loop och ett generiskt for
loop.
En siffra
for
slinga har följande 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
Det tredje uttrycket i en siffra
for
loop är steget genom vilket loopen kommer att öka. Detta gör det enkelt att göra omvända slingor:for a=10, 1, -1 do print(a) --> 10, 9, 8, 7, 6, etc. end
Om steguttrycket lämnas ut antar Lua ett standardsteg på 1.
for a=1, 10 do print(a) --> 1, 2, 3, 4, 5, etc. end
Observera också att loopvariabeln är lokal för
for
loopen. Det kommer inte att existera efter att slingan är över.
Generiskt
for
slingor arbetar genom alla värden som en iteratorfunktion returnerar:for key, value in pairs({"some", "table"}) do print(key, value) --> 1 some --> 2 table end
Lua tillhandahåller flera inbyggda iteratorer (t.ex.
pairs
,ipairs
), och användare kan definiera sina egna anpassade iteratorer som de också kan använda med generiskafor
slingor.
gör block
local a = 10
do
print(a) --> 10
local a = 20
print(a) --> 20
end
print(a) --> 10
Några knepiga saker
Ibland uppträder Lua inte som man skulle tänka efter att ha läst dokumentationen. Några av dessa fall är:
Noll och ingenting är inte desamma (GEMENSAMT PITFALL!)
Som förväntat table.insert(my_table, 20)
till värdet 20
till tabellen, och table.insert(my_table, 5, 20)
lägger till värdet 20 på 5: e positionen. Vad gör table.insert(my_table, 5, nil)
men? Man kan förvänta sig att det behandlar nil
som inget argument alls, och sätter in värdet 5
i slutet av tabellen, men det lägger faktiskt till värdet nil
på nil
femte position. När är detta ett 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)
En liknande sak händer med 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
Detta kan också leda till fel vid användning av tredjepartskod. Om till exempel dokumentation av vissa funktionstillstånd "avkastning munkar om tur, noll annars", genomförandet kanske ser ut ungefär som det här
function func(lucky)
if lucky then
return "donuts"
end
end
denna implementering kan tyckas rimlig till en början; det returnerar munkar när det måste, och när du skriver result = func(false)
resultat kommer att innehålla värdet nil
.
Men om man skulle skriva print(tostring(func(false)))
skulle lua kasta ett fel som ser något ut som det här stdin:1: bad argument #1 to 'tostring' (value expected)
Varför är det så? tostring
får tydligt ett argument, även om det är nil
. Fel. func returnerar ingenting alls, så tostring(func(false))
är detsamma som tostring()
och INTE detsamma som tostring(nil)
.
Fel som säger "förväntat värde" är en stark indikation på att detta kan vara källan till problemet.
Lämnar luckor i matriser
Detta är en enorm fallgrop om du är ny på lua, och det finns mycket information i tabellerna
Hej världen
Detta är hej världskod:
print("Hello World!")
Hur det fungerar? Det är enkelt! Lua kör funktionen Print print()
och använder strängen "Hello World"
som argument.