Szukaj…


Uwagi

Logo Lua

Lua to minimalistyczny, lekki i możliwy do osadzenia język skryptowy. Jest projektowany, wdrażany i utrzymywany przez zespół z PUC-Rio , Papieskiego Katolickiego Uniwersytetu Rio de Janeiro w Brazylii. Lista mailingowa jest otwarta, aby się zaangażować.

Typowe przypadki użycia dla Lua obejmują pisanie skryptów gier wideo, rozszerzanie aplikacji o wtyczki i konfiguracje, pakowanie logiki biznesowej wysokiego poziomu lub po prostu osadzanie w urządzeniach takich jak telewizory, samochody itp.

W przypadku zadań o wysokiej wydajności istnieje niezależna implementacja za pomocą kompilatora just-in-time o nazwie LuaJIT .

Wersje

Wersja Notatki Data wydania
1.0 Pierwsze, niepubliczne wydanie. 1993-07-28
1.1 Pierwsze publiczne wydanie. Dokument konferencyjny opisujący to. 1994-07-08
2.1 Począwszy od Lua 2.1, Lua stał się swobodnie dostępny do wszystkich celów, w tym do zastosowań komercyjnych. Gazeta opisująca to. 1995-02-07
2.2 Długie ciągi, interfejs debugowania, lepsze śledzenie stosu 1995-11-28
2.4 Zewnętrzny kompilator luac 1996-05-14
2.5 Funkcje dopasowania wzorców i vararg. 1996-11-19
3.0 Wprowadzono auxlib, bibliotekę pomagającą pisać biblioteki Lua 01.07.1997
3.1 Anonimowe funkcje i zamknięcia funkcji poprzez „podwyższenie wartości”. 1998-07-11
3.2 Debuguj bibliotekę i nowe funkcje tabeli 1999-07-08
3.2.2 2000-02-22
4.0 Wiele stanów, instrukcje „for”, aktualizacja interfejsu API. 2000-11-06
4.0.1 2002-07-04
5.0 Coroutines, metatables, pełny zakres leksykalny, ogony, booleany przechodzą na licencję MIT. 2003-04-11
5.0.3 2006-06-26
5.1 Modernizacja systemu modułów, przyrostowy moduł wyrzucania elementów bezużytecznych, metatable dla wszystkich typów, przeróbka luaconf.h, parser w pełni poprawny, argumenty variadic. 2006-02-21
5.1.5 17.02.2012
5.2 Awaryjny pojemnik na śmieci, goto, finalizatory tabel. 16.12.2011
5.2.4 2015-03-07
5.3 Podstawowa obsługa UTF-8, operacje bitowe, liczby całkowite 32 / 64bit. 2015-01-12
5.3.4 Ostatnia wersja. 2017-01-12

Instalacja

Pliki binarne

Pliki binarne Lua są dostarczane przez większość dystrybucji GNU / Linux jako pakiet.

Na przykład w Debianie, Ubuntu i ich pochodnych można je uzyskać, wykonując to:

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

Istnieje kilka półoficjalnych wersji dla Windows, MacOS i niektórych innych systemów operacyjnych hostowanych w SourceForge .

Użytkownicy Apple mogą również łatwo zainstalować Lua za pomocą Homebrew :

brew install lua

(Obecnie Homebrew ma 5.2.4, dla 5.3 patrz Homebrew / wersje .)

Źródło

Źródło jest dostępne na oficjalnej stronie . Pozyskiwanie źródeł i samej kompilacji powinno być trywialne. W systemach Linux wystarczające powinny być:

$ 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

W powyższym przykładzie w zasadzie pobieramy źródłowy tarball z oficjalnej strony, weryfikujemy jego sumę kontrolną oraz wyodrębniamy i wykonujemy make . (Sprawdź dwukrotnie sumę kontrolną na oficjalnej stronie ).

Uwaga: musisz określić, jaki cel kompilacji chcesz. W tym przykładzie podaliśmy linux . Inne dostępne cele kompilacji to solaris , aix , bsd , freebsd , macosx , mingw itp. Więcej informacji można znaleźć w doc/readme.html , który znajduje się w źródle. ( Najnowszą wersję README można również znaleźć w Internecie .)

Moduły

Standardowe biblioteki są ograniczone do prymitywów:

  • coroutine - funkcjonalność zarządzania coroutine
  • debug - zaczepy i narzędzia do debugowania
  • io - podstawowe operacje podstawowe IO
  • package - funkcjonalność zarządzania modułem
  • string - funkcja dopasowywania wzorca do łańcucha i Lua
  • table - prymitywy do radzenia sobie z niezbędnymi, ale złożonymi tabelami typu Lua
  • os - podstawowe operacje systemu operacyjnego
  • utf8 - podstawowe prymitywy UTF-8 (od Lua 5.3)

Wszystkie te biblioteki można wyłączyć dla określonej kompilacji lub załadować w czasie wykonywania.

Biblioteki Lua innych firm i infrastruktura do dystrybucji modułów są rzadkie, ale poprawiają się. Projekty takie jak LuaRocks , Lua Toolbox i LuaDist poprawiają sytuację. Wiele informacji i sugestii można znaleźć na starszej Wiki Lua , ale pamiętaj, że niektóre z tych informacji są dość stare i nieaktualne.

Komentarze

Komentarze jednowierszowe w Lua zaczynają się od -- i trwają do końca linii:

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

Blokowanie komentarzy zaczyna się od --[[ i kończy się na ]] :

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

Komentarze blokowe używają tego samego stylu separatorów co długie łańcuchy; między nawiasami można dodać dowolną liczbę znaków równości, aby wyznaczyć komentarz:

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

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

Zgrabną sztuczką do komentowania fragmentów kodu jest otaczanie go --[[ i --]] :

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

Aby ponownie aktywować fragment, po prostu dodaj - do sekwencji otwierającej komentarz:

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

W ten sposób sekwencja -- w pierwszym wierszu rozpoczyna komentarz jednowierszowy, podobnie jak ostatni wiersz, a instrukcja print nie jest komentowana.

Idąc o krok dalej, dwa bloki kodu można skonfigurować w taki sposób, że jeśli pierwszy blok zostanie skomentowany, drugi nie będzie, i odwrotnie:

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

Aby uaktywnić drugi fragment, wyłączając pierwszy fragment, usuń wiodące - w pierwszym wierszu:

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

Wykonywanie programów Lua

Zwykle Lua jest wysyłana z dwoma plikami binarnymi:

  • lua - samodzielny interpreter i interaktywna powłoka
  • luac - kompilator kodu bajtowego

Powiedzmy, że mamy przykładowy program ( bottles_of_mate.lua ) taki jak ten:

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

Sam program można uruchomić, wykonując następujące czynności w powłoce:

$ lua bottles_of_mate.lua

Dane wyjściowe powinny wyglądać tak, działając w nieskończonej pętli:

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.
...

Możesz skompilować program do kodu bajtowego Lua, wykonując następujące czynności w swojej powłoce:

$ luac bottles_of_mate.lua -o bottles_of_mate.luac

Dostępna jest również lista kodów bajtowych, wykonując następujące czynności:

$ 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

Pierwsze kroki

zmienne

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.

typy

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!"

Specjalny typ nil

Innym typem w Lua jest nil . Wartość tylko w nil typu jest nil . nil istnieje, aby różnić się od wszystkich innych wartości w Lua. Jest to rodzaj wartości bez wartości.

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!

wyrażenia

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

Definiowanie funkcji

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

booleany

Tylko false i nil traktowane jako fałsz, wszystko inne, w tym 0 i pusty ciąg znaków, są traktowane jako prawda.

zbieranie śmieci

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

stoły

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.

To są podstawy, ale jest sekcja o tabelach z dodatkowymi informacjami.

warunki

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

dla pętli

Istnieją dwa typy pętli for w Lua: numeryczna for pętli i ogólna for pętli.

  • Liczbowy for pętli ma postać następującą:

    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
    

    Trzecie wyrażenie w liczbowej pętli for jest krokiem, o który pętla będzie się zwiększać. Ułatwia to wykonywanie pętli zwrotnych:

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

    Jeśli wyrażenie kroku zostanie pominięte, Lua przyjmuje domyślny krok 1.

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

    Zauważ również, że zmienna pętli jest lokalna for pętli for . Nie będzie istniał po zakończeniu pętli.

  • Ogólny for pętli działa na wszystkich wartościach zwracanych przez funkcję iteratora:

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

    Lua zapewnia kilka wbudowanych iteratorów (np. pairs , pairs ipairs ), a użytkownicy mogą definiować własne niestandardowe iteratory, aby używać ich z ogólnymi for pętli.

robić bloki

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

Niektóre trudne rzeczy

Czasami Lua nie zachowuje się tak, jak można by pomyśleć po przeczytaniu dokumentacji. Niektóre z tych przypadków to:

Zero i Nic nie są takie same (WSPÓLNY PITFALL!)

Zgodnie z oczekiwaniami table.insert(my_table, 20) dodaje wartość 20 do tabeli, a table.insert(my_table, 5, 20) dodaje wartość 20 na 5. pozycji. Co jednak robi table.insert(my_table, 5, nil) ? Można się spodziewać, że będzie traktować nil jako żaden argument i wstawi wartość 5 na końcu tabeli, ale w rzeczywistości dodaje wartość nil na 5. pozycji tabeli. Kiedy to jest 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)

Podobnie dzieje się z 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

Może to również prowadzić do błędów podczas korzystania z kodu strony trzeciej. Jeśli, na przykład, dokumentacja niektórych funkcji stwierdza „zwraca pączki, jeśli ma szczęście, w przeciwnym razie zero”, implementacja może wyglądać mniej więcej tak

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

to wdrożenie może początkowo wydawać się rozsądne; zwraca pączki, gdy jest to konieczne, a po wpisaniu result = func(false) wynik będzie zawierał wartość nil .

Gdyby jednak napisać print(tostring(func(false))) lua wyrzuciłby błąd, który wygląda stdin:1: bad argument #1 to 'tostring' (value expected) tak stdin:1: bad argument #1 to 'tostring' (value expected)

Dlaczego? tostring wyraźnie otrzymuje argument, mimo że jest nil . Źle. func w ogóle nic nie zwraca, więc tostring(func(false)) jest taki sam jak tostring() i NIE jest taki sam jak tostring(nil) .

Błędy mówiące o „oczekiwanej wartości” są silnym sygnałem, że może to być przyczyną problemu.

Pozostawiając luki w tablicach

To wielka pułapka, jeśli jesteś nowy w lua, aw kategorii tabel jest wiele informacji

Witaj świecie

To jest kod cześć świata:

print("Hello World!")

Jak to działa? To proste! Lua wykonuje funkcję print() i wykorzystuje ciąg "Hello World" jako argument.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow