Синтаксис и пунктуация в Lua
Формат программы и лексика
Синтаксис Lua опирается на Modula-2 и Oberon: свободный формат записи, операторы разделяются пробельными символами. Точка с запятой допустима, но обычно не нужна. Язык регистрозависим: ключевые слова только в нижнем регистре; foo и Foo — разные идентификаторы.
Идентификаторы — буквы, цифры и _, не с цифры и не совпадают с ключевым словом. Имена с ведущим _ в руководстве отнесены к системным (метаметоды __index и т.п.) — в своём коде так лучше не начинать имена.
Полный список — в статье Ключевые слова. В ядре 22 зарезервированных слова:
and, break, do, else, elseif, end, false, for, function, goto, if, in, local, nil, not, or, repeat, return, then, true, until, while.
Комментарии
Как в Ada, SQL и VHDL:
- Строчный — с
--до конца строки (может стоять в конце строки с кодом). - Блочный —
--[[…]](вложенные скобки задают уровень, как у длинных строк).
-- однострочный
local t = {1, 2, 3} -- пояснение к выражению
--[[
многострочный
комментарий
]]
Приём "закомментировать блок одной строкой" — если в --[[ вставить пробел (-- [[), открывающая пара перестаёт быть блочным комментарием, а закрывающая ]] на отдельной строке с -- превращается в обычный строчный комментарий — удобно временно отключать фрагмент кода.
Названия знаков по-английски и по-русски: Знаки препинания и символы в IT.
Знаки препинания
Для новичков один из самых частых источников путаницы — что означают символы вроде .., ;, ' или :, особенно когда они встречаются в непривычных комбинациях. В Lua многие знаки работают иначе, чем в других языках (например, JavaScript или Python), поэтому важно чётко понимать их назначение.
Кавычки
Кавычки (' и ").
В Lua оба типа кавычек допустимы для строк, и выбор зависит только от содержимого строки и стиля кода.
local name = "Тимур"
local message = 'Hello from Lua!'
Разбор:
localсоздаёт локальную переменную в текущем блоке; строка в кавычках — литерал типаstring.- Одинарные и двойные кавычки эквивалентны: выбирайте тот вид, где меньше экранирования внутри текста.
- При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Оба варианта работают одинаково. Разница — только в удобстве экранирования. Удобно использовать двойные кавычки, если внутри строки есть апостроф:
local text = "It's a beautiful day"
Разбор:
localсоздаёт локальную переменную в текущем блоке; строка в кавычках — литерал типаstring.- Одинарные и двойные кавычки эквивалентны: выбирайте тот вид, где меньше экранирования внутри текста.
- При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Удобно использовать одинарные, если внутри есть цитата:
local quote = 'He said, "Welcome!"'
Разбор:
localсоздаёт локальную переменную в текущем блоке; строка в кавычках — литерал типаstring.- Одинарные и двойные кавычки эквивалентны: выбирайте тот вид, где меньше экранирования внутри текста.
- При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Апострофы
Апострофы (’), например, “smart quotes” из Word — не являются частью синтаксиса и вызовут ошибку:
local wrong = “This won’t work” -- ОШИБКА: неверные кавычки
Разбор:
- "Умные" кавычки из текстовых редакторов не являются синтаксисом Lua — интерпретатор их не примет.
- Комментарии после
--поясняют ожидаемый результат; при запуске интерпретатор их игнорирует. - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Точки с запятой
Точки с запятой (;) — опциональны, но редко используются. В Lua точки с запятой не обязательны. Интерпретатор автоматически определяет конец выражения (по аналогии с ASI в JavaScript, но проще).
print("Hello")
local x = 10
local y = 20
Разбор:
- Ключевые вызовы в фрагменте:
print(). - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Вы можете использовать ;, если хотите:
print("Hello"); local x = 10; local y = 20;
Разбор:
- Точка с запятой в Lua необязательна; здесь она просто разделяет несколько выражений в одной строке.
- Ключевые вызовы в фрагменте:
print(). - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Но в сообществе Lua принято не ставить точки с запятой, если только вы не пишете несколько выражений в одной строке.
Запятая
Запятая (,) — разделитель элементов. Используется повсеместно для разделения параметров функций, элементов таблиц и нескольких значений при присваивании.
-- Параметры функции
function greet(name, age)
print(name .. " is " .. age .. " years old")
end
-- Таблица
local colors = {"red", "green", "blue"}
-- Множественное присваивание
local x, y, z = 1, 2, 3
Разбор:
functionобъявляет функцию;endзакрывает тело. Имя послеfunctionстановится ссылкой на вызываемый объект.- Оператор
..склеивает строки (и автоматически приводит числа к строке при конкатенации). - Фигурные скобки
{}создают таблицу: можно задать поляkey = valueи/или элементы-массив с индексами с 1. - Ключевые вызовы в фрагменте:
print(). - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
В отличие от JavaScript, в таблицах можно ставить запятую после последнего элемента — это не ошибка:
local fruits = {
"apple",
"banana",
}
Разбор:
- Фигурные скобки
{}создают таблицу: можно задать поляkey = valueи/или элементы-массив с индексами с 1. - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Это удобно при добавлении новых элементов — не нужно менять предыдущую строку.
Точка и двоеточие
Точка (.) и двоеточие (:) — доступ к полям и методам. Это одна из ключевых особенностей Lua, особенно при работе с таблицами и ООП.
Чтобы получить доступ к полю или вызвать функцию, нужно поставить точку.
Пример:
local person = {name = "Bob", age = 30}
print(person.name) -- -> "Bob"
function person.greet()
print("Hi, I'm " .. person.name)
end
person.greet() -- вызов функции
Разбор:
- Одинарные и двойные кавычки эквивалентны: выбирайте тот вид, где меньше экранирования внутри текста.
- Оператор
..склеивает строки (и автоматически приводит числа к строке при конкатенации). - Фигурные скобки
{}создают таблицу: можно задать поляkey = valueи/или элементы-массив с индексами с 1. - Ключевые вызовы в фрагменте:
print(). - Комментарии после
--поясняют ожидаемый результат; при запуске интерпретатор их игнорирует. - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Вызывать методы можно через двоеточие, это синтаксический сахар для передачи объекта как первого аргумента (self).
function person:greet()
print("Hi, I'm " .. self.name) -- self = person
end
person:greet() -- то же самое, что person.greet(person)
Разбор:
functionобъявляет функцию;endзакрывает тело. Имя послеfunctionстановится ссылкой на вызываемый объект.- Синтаксис
obj:method()передаётobjпервым аргументом (self) — удобный стиль для методов таблиц. - Оператор
..склеивает строки (и автоматически приводит числа к строке при конкатенации). - Ключевые вызовы в фрагменте:
print(). - Комментарии после
--поясняют ожидаемый результат; при запуске интерпретатор их игнорирует. - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
То есть, эти два метода будут эквивалентны:
person:greet()
person.greet(person)
Разбор:
- Код выполняется построчно: каждая инструкция использует значения, созданные строками выше.
- При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Две точки
Две точки (..) — конкатенация строк. В Lua нет оператора + для строк (как в JavaScript). Вместо этого используются две точки.
local first = "Hello"
local last = "World"
local full = first .. ", " .. last -- -> "Hello, World"
Разбор:
localсоздаёт локальную переменную в текущем блоке; строка в кавычках — литерал типаstring.- Оператор
..склеивает строки (и автоматически приводит числа к строке при конкатенации). - Комментарии после
--поясняют ожидаемый результат; при запуске интерпретатор их игнорирует. - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Будьте осторожны: .. имеет низкий приоритет, лучше брать в скобки при смешивании с числами:
print("Value: " .. 5 + 3) -- ОШИБКА: попытка склеить строку и результат 5+3
print("Value: " .. (5 + 3)) -- ПРАВИЛЬНО: -> "Value: 8"
Разбор:
- Оператор
..склеивает строки (и автоматически приводит числа к строке при конкатенации). - Приоритет
..ниже, чем у+: без скобок сначала выполнится арифметика, затем конкатенация — отсюда ошибка в первой строке. - Ключевые вызовы в фрагменте:
print(). - Комментарии после
--поясняют ожидаемый результат; при запуске интерпретатор их игнорирует. - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Подчёркивание
Подчёркивание (_) — соглашения и именование. Как и в других языках, _ используется по стилю, но не имеет специального смысла для интерпретатора.
_ часто используется как имя "игнорируемой" переменной, часто используется в циклах for, когда индекс не нужен:
for _, value in ipairs(fruits) do
print(value)
end
Разбор:
ipairsобходит последовательную часть таблицы (индексы 1,2,3…);pairs— все пары ключ-значение.- Цикл
forповторяет тело: в числовой форме перебирает диапазон, в generic — элементы через итератор. - Ключевые вызовы в фрагменте:
ipairs(),print(). - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
_name — соглашение о внутреннем/приватном поле:
local config = {
_api_key = "12345", -- не для внешнего использования
public_url = "https://..."
}
Разбор:
- Оператор
..склеивает строки (и автоматически приводит числа к строке при конкатенации). - Фигурные скобки
{}создают таблицу: можно задать поляkey = valueи/или элементы-массив с индексами с 1. - Комментарии после
--поясняют ожидаемый результат; при запуске интерпретатор их игнорирует. - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Это не приватность, просто сигнал другим разработчикам.
__name — зарезервировано для метаметодов:
mt.__index = function() ... end
mt.__add = function() ... end
Разбор:
- Оператор
..склеивает строки (и автоматически приводит числа к строке при конкатенации). setmetatableсвязывает таблицу с метатаблицей; поля__…задают перехват операций (индекс, арифметика, вызов).- При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Такие имена — часть механизма метатаблиц.
_ в числах (Luau) — читаемость:
local billion = 1_000_000_000 -- работает в Luau
Разбор:
- Комментарии после
--поясняют ожидаемый результат; при запуске интерпретатор их игнорирует. - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
В Luau (но не в классическом Lua) можно использовать _ как разделитель. В стандартном Lua это вызовет ошибку.
Прочие операторы
Вот важное отличие от JavaScript, C# и Java:
- В Lua 5.1 побитовые операторы
|,&,~в ядре отсутствуют — нужна библиотекаbit32. - С Lua 5.3+ в ядре есть
&,|,~,<<,>>(исключение:^— возведение в степень, не XOR). - Нет логических
||и&&— вместо нихorиand.
В Lua используются слова:
if x == 1 or y == 2 then
print("At least one condition is true")
end
if x == 1 and y == 2 then
print("Both conditions are true")
end
local result = a or "default" -- как ?? в C# или || в JS
Разбор:
if … then … endвыбирает ветку по truthiness: ложными считаются толькоnilиfalse.- Логика записывается словами
and/or/not, а не символами&&/||/!как в C-подобных языках. - Выражение
a or "default"— идиома: еслиaложно (nil/false), берётся значение справа. - Ключевые вызовы в фрагменте:
print(). - Комментарии после
--поясняют ожидаемый результат; при запуске интерпретатор их игнорирует. - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Это делает код более читаемым, но менее компактным.
В Lua 5.3+ и в Luau побитовые операторы записываются символами (&, |, ~, <<, >>). В Lua 5.1 (включая чистый Roblox-совместимый код без расширений) — bit32.band, bit32.bor и т.д.
local flags = permission_read | permission_write
Разбор:
- Код выполняется построчно: каждая инструкция использует значения, созданные строками выше.
- При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Важно учесть кое-что ещё. В классическом Lua : (двоеточие) используется только для вызова методов с self. В Luau : также используется для аннотаций типов.
-- Luau:
local name: string = "Alice"
function greet(name: string): string
return "Hello, " .. name
end
Разбор:
functionобъявляет функцию;endзакрывает тело. Имя послеfunctionстановится ссылкой на вызываемый объект.- Оператор
..склеивает строки (и автоматически приводит числа к строке при конкатенации). returnзавершает функцию и может вернуть несколько значений через запятую.- Двоеточие после имени — аннотация типа Luau; на выполнение в рантайме не влияет, помогает анализатору и IDE.
- При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Это не работает в чистом Lua — будет ошибка синтаксиса. И если видите : type, значит, код написан для Roblox Studio или Luau CLI.
В Lua нет шаблонных строк, как в JavaScript (Hello ${name}). Чтобы вставлять переменные в строки, используйте конкатенацию:
local name = "Timur"
print("Hello, " .. name .. "!") -- единственный способ
Разбор:
localсоздаёт локальную переменную в текущем блоке; строка в кавычках — литерал типаstring.- Оператор
..склеивает строки (и автоматически приводит числа к строке при конкатенации). - Ключевые вызовы в фрагменте:
print(). - Комментарии после
--поясняют ожидаемый результат; при запуске интерпретатор их игнорирует. - При переносе в свой проект сохраните порядок шагов и проверьте результат через
printили отладчик.
Lua делает ставку на читаемость и простоту, поэтому использует слова вместо символов (or, and), отказывается от лишних знаков (;), даёт гибкость через таблицы и метатаблицы. Поэтому, если вы уже знакомы с другими скриптовыми языками, может быть непривычно.