Перейти к основному содержимому

Синтаксис и пунктуация в 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), отказывается от лишних знаков (;), даёт гибкость через таблицы и метатаблицы. Поэтому, если вы уже знакомы с другими скриптовыми языками, может быть непривычно.