Lua учебник
Начало работы с Lua
Поиск…
замечания
Lua - минималистичный, легкий и встраиваемый язык сценариев. Он разрабатывается, внедряется и поддерживается командой в PUC-Rio , Папском католическом университете Рио-де-Жанейро в Бразилии. Список рассылки открыт для участия.
Обычные прецеденты для Lua включают в себя скриптовые видеоигры, расширение приложений с помощью плагинов и конфигов, перенос некоторых бизнес-логик высокого уровня или просто внедрение в такие устройства, как телевизоры, автомобили и т. Д.
Для высокопроизводительных задач существует независимая реализация с использованием доступного во времени компилятора LuaJIT .
Версии
Версия | Заметки | Дата выхода |
---|---|---|
1,0 | Первоначальный, непубличный выпуск. | 1993-07-28 |
1,1 | Первый публичный выпуск. В документе описывается это. | 1994-07-08 |
2,1 | Начиная с Lua 2.1, Lua стал свободно доступным для всех целей, включая коммерческое использование. Журнал, описывающий его. | 1995-02-07 |
2,2 | Длинные строки, интерфейс отладки, лучшие трассировки стека | 1995-11-28 |
2,4 | Внешний компилятор luac | 1996-05-14 |
2.5 | Совмещение шаблонов и функции vararg. | 1996-11-19 |
3.0 | Введена auxlib, библиотека для помощи в написании библиотек Lua | 1997-07-01 |
3,1 | Анонимные функции и закрытие функций с помощью «upvalues». | 1998-07-11 |
3,2 | Библиотека отладки и новые функции таблицы | 1999-07-08 |
3.2.2 | 2000-02-22 | |
4,0 | Несколько состояний, «для» операторов, API revamp. | 2000-11-06 |
4.0.1 | 2002-07-04 | |
5.0 | Coroutines, metatables, полный лексический охват, tail calls, booleans переходят на лицензию MIT. | 2003-04-11 |
5.0.3 | 2006-06-26 | |
5,1 | Обновление системы модулей, инкрементный сборщик мусора, метаданные для всех типов, luaconf.h revamp, полностью реентеративный парсер, вариативные аргументы. | 2006-02-21 |
5.1.5 | 2012-02-17 | |
5,2 | Экстренный сборщик мусора, goto, финализаторы для столов. | 2011-12-16 |
5.2.4 | 2015-03-07 | |
5,3 | Базовая поддержка UTF-8, побитовые операции, 32/64-битные целые числа. | 2015-01-12 |
5.3.4 | Последняя версия. | 2017-01-12 |
Монтаж
Бинарные
Бинарные файлы Lua предоставляются большинством дистрибутивов GNU / Linux в качестве пакета.
Например, на Debian, Ubuntu и их производных можно получить, выполнив следующее:
sudo apt-get install lua50
sudo apt-get install lua51
sudo apt-get install lua52
В SourceForge есть некоторые полуофициальные сборки для Windows, MacOS и некоторых других операционных систем.
Пользователи Apple также могут легко установить Lua с помощью Homebrew :
brew install lua
(В настоящее время Homebrew имеет 5.2.4, для 5.3 см. Homebrew / версии .)
Источник
Источник доступен на официальной странице . Приобретение источников и их создание должны быть тривиальными. В системах Linux должно быть достаточно:
$ 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
В приведенном выше примере мы в основном загружаем исходный tarball
с официального сайта, проверяем его контрольную сумму и извлекаем и выполняем make
. (Дважды проверьте контрольную сумму на официальной странице .)
Примечание: вы должны указать, какую цель сборки вы хотите. В этом примере мы указали linux
. Другие доступные цели сборки включают solaris
, aix
, bsd
, freebsd
, macosx
, mingw
и т. Д. Для получения более подробной информации macosx
doc/readme.html
, который включен в источник. (Вы также можете найти последнюю версию README в Интернете .)
Модули
Стандартные библиотеки ограничены примитивами:
- Функции управления сопрограммой
coroutine
- coroutine -
debug
- отладочные крючки и инструменты -
io
- основные примитивы ввода-вывода - функциональность управления
package
модулей -
string
- строка и функциональная совместимость с Lua -
table
- примитивы для обработки существенного, но сложного типа Lua - таблицы -
os
- основные операции ОС -
utf8
- базовые примитивы UTF-8 (начиная с Lua 5.3)
Все эти библиотеки могут быть отключены для конкретной сборки или загружены во время выполнения.
Сторонние библиотеки Lua и инфраструктура для распространения модулей редки, но улучшаются. Такие проекты, как LuaRocks , Lua Toolbox и LuaDist , улучшают ситуацию. Много информации и множество предложений можно найти на старшей Lua Wiki , но имейте в виду, что некоторые из этих данных довольно старые и устаревшие.
Комментарии
Однострочные комментарии в Lua начинаются с --
и продолжаются до конца строки:
-- this is single line comment
-- need another line
-- huh?
Заблокировать комментарии начинаются с --[[
и заканчиваются с ]]
:
--[[
This is block comment.
So, it can go on...
and on...
and on....
]]
Блочные комментарии используют тот же стиль разделителей, что и длинные строки; любое количество знаков равенства может быть добавлено между скобками, чтобы разграничить комментарий:
--[=[
This is also a block comment
We can include "]]" inside this comment
--]=]
--[==[
This is also a block comment
We can include "]=]" inside this comment
--]==]
Чистый трюк, чтобы прокомментировать фрагменты кода, состоит в том, чтобы окружить его --[[
и --]]
:
--[[
print'Lua is lovely'
--]]
Чтобы повторно активировать кусок, просто добавьте a -
в последовательность открытия комментария:
---[[
print'Lua is lovely'
--]]
Таким образом, последовательность --
в первой строке запускает однострочный комментарий, как и предыдущая строка, и оператор print
не закомментирован.
Сделав еще один шаг, два блока кода могут быть настроены таким образом, что если первый блок будет закомментирован, второй не будет, и наоборот:
---[[
print 'Lua is love'
--[=[]]
print 'Lua is life'
--]=]
Чтобы активировать второй фрагмент при отключении первого фрагмента, удалите ведущий -
в первой строке:
--[[
print 'Lua is love'
--[=[]]
print 'Lua is life'
--]=]
Выполнение программ Lua
Обычно Lua поставляется с двумя двоичными файлами:
-
lua
- автономный интерпретатор и интерактивная оболочка - компилятор
luac
- байт-код
Допустим, у нас есть пример программы ( 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
Сама программа может быть запущена, выполнив следующую команду в своей оболочке:
$ lua bottles_of_mate.lua
Результат должен выглядеть следующим образом: бег в бесконечном цикле:
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.
...
Вы можете скомпилировать программу в байт-код Lua, выполнив следующую команду в своей оболочке:
$ luac bottles_of_mate.lua -o bottles_of_mate.luac
Также перечисление байт-кода доступно, выполнив следующие действия:
$ 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
Начиная
переменные
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.
типы
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!"
Специальный тип nil
Другой тип в Lua - nil
. Единственное значение в nil
типа является nil
. nil
существует, чтобы отличаться от всех других значений в Lua. Это своего рода неценовое значение.
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!
выражения
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
Определение функций
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
булевы
Только false
и nil
оцениваются как false, все остальное, включая 0
а пустая строка оценивается как истина.
вывоз мусора
tab = {"lots", "of", "data"}
tab = nil; collectgarbage()
-- tab does no longer exist, and doesn't take up memory anymore.
таблицы
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.
Это основы, но есть раздел о таблицах с дополнительной информацией.
условия
if (condition) then
-- do something
elseif (other_condition) then
-- do something else
else
-- do something
end
для петель
Существует два типа цикла for
в Lua: числовое значение for
цикла и общий for
цикла.
Цифры
for
цикла имеют следующий вид: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
Третье выражение в числовой
for
цикла представляет собой этап , по которому цикл будет увеличиваться. Это упрощает выполнение обратных циклов:for a=10, 1, -1 do print(a) --> 10, 9, 8, 7, 6, etc. end
Если выражение шага не указано, Lua принимает шаг по умолчанию 1.
for a=1, 10 do print(a) --> 1, 2, 3, 4, 5, etc. end
Также обратите внимание, что переменная цикла является локальной
for
циклаfor
. Он не будет существовать после завершения цикла.
Общие
for
циклов работают через все значения, возвращаемые функцией итератора:for key, value in pairs({"some", "table"}) do print(key, value) --> 1 some --> 2 table end
Lua предоставляет несколько встроенных итераторов (например,
pairs
,ipairs
), и пользователи могут определять свои собственные итераторы, а также использовать общиеfor
циклов.
делать блоки
local a = 10
do
print(a) --> 10
local a = 20
print(a) --> 20
end
print(a) --> 10
Некоторые сложные вещи
Иногда Lua не ведет себя так, как можно было бы подумать после прочтения документации. Некоторые из этих случаев:
Ниль и Ничто не то же самое (ОБЩИЙ ПИТФАЛ!)
Как и ожидалось, table.insert(my_table, 20)
добавляет значение 20
в таблицу, а table.insert(my_table, 5, 20)
добавляет значение 20 в 5-ю позицию. Что делает table.insert(my_table, 5, nil)
? Можно было бы ожидать, что он будет обрабатывать nil
как никакой аргумент вообще и вставить значение 5
в конце таблицы, но фактически добавляет значение nil
в пятую позицию таблицы. Когда это проблема?
(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)
Аналогичная ситуация происходит с 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
Это также может привести к ошибкам при использовании стороннего кода. Если, например, документация некоторых состояний функций «возвращает пончики, если повезет, нуль в противном случае», реализация может выглядеть примерно так:
function func(lucky)
if lucky then
return "donuts"
end
end
эта реализация может показаться разумной вначале; он возвращает пончики, когда это необходимо, и когда вы вводите result = func(false)
результат будет содержать значение nil
.
Тем не менее, если нужно написать print(tostring(func(false)))
lua выдаст ошибку, которая выглядит примерно так stdin:1: bad argument #1 to 'tostring' (value expected)
Это почему? tostring
явно получает аргумент, хотя его nil
. Неправильно. func ничего не возвращает, поэтому tostring(func(false))
является тем же, что и tostring()
и NOT то же, что и tostring(nil)
.
Ошибки, говорящие о «ожидаемом значении», являются убедительным доказательством того, что это может быть источником проблемы.
Устранение пробелов в массивах
Это огромная ошибка, если вы новичок в lua, и в таблице есть много информации
Привет, мир
Это приветственный мировой код:
print("Hello World!")
Как это устроено? Это просто! Lua выполняет функцию print()
и использует строку "Hello World"
качестве аргумента.