Логические операторы
Одного условия часто не хватает. Пустить игрока в комнату можно только если у него есть и пропуск, и он не в чёрном списке. Отправить уведомление нужно если истёк срок или произошла ошибка. Скидку давать только если покупатель зарегистрирован и сумма больше 1000.
Для таких составных проверок используются три логических оператора: and, or и not.
and — оба условия должны быть истинны
and возвращает истину только если оба операнда истинны. Если хоть один ложен — результат ложен.
local age = 17
local hasTicket = true
if age >= 16 and hasTicket then
print("Проходи")
else
print("Нет доступа")
end
local temperature = 85
local pressure = 3.2
if temperature > 100 or pressure > 5.0 then
print("Система перегрева: аварийное отключение")
end
local score = 92
local attendance = 88
if score >= 90 and attendance >= 85 then
print("Отличник — зачислен на стипендию")
elseif score >= 70 and attendance >= 75 then
print("Допущен к экзамену")
else
print("Не допущен")
end
Таблица истинности and:
| A | B | A and B |
|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
or — достаточно одного истинного условия
or возвращает истину если хотя бы один операнд истинен. Ложен только если оба ложны.
local isAdmin = false
local isModerator = true
if isAdmin or isModerator then
print("Доступ к панели управления разрешён")
end
local fileExtension = "jpeg"
if fileExtension == "jpg" or fileExtension == "jpeg" or fileExtension == "png" then
print("Это изображение, можно загрузить")
else
print("Неподдерживаемый формат файла")
end
local errorCode = 503
local retryCount = 5
if errorCode == 500 or errorCode == 502 or errorCode == 503 then
if retryCount < 3 then
print("Повторяем запрос...")
else
print("Сервер недоступен, прекращаем попытки")
end
end
Таблица истинности or:
| A | B | A or B |
|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
not — инверсия
not переворачивает логическое значение: true становится false, false становится true.
local isLoggedIn = false
if not isLoggedIn then
print("Ты не вошёл в систему. Перенаправляем на страницу входа.")
end
local isBanned = false
local hasVerifiedEmail = true
if not isBanned and hasVerifiedEmail then
print("Аккаунт активен")
end
local isWeekend = true
local isHoliday = false
if not (isWeekend or isHoliday) then
print("Рабочий день — офис открыт")
else
print("Выходной день — офис закрыт")
end
Приоритет операторов
Когда в выражении несколько операторов, порядок вычисления такой:
not — первым
and — вторым
or — последним
-- Это выражение:
if a or b and not c then
-- Читается как:
if a or (b and (not c)) then
Когда не уверен — ставь скобки явно:
local isPremium = true
local hasDiscount = false
local cartValue = 1500
-- Скидка если: (пользователь премиум или есть промокод) И корзина больше 1000
if (isPremium or hasDiscount) and cartValue > 1000 then
print("Скидка 15% применена")
end
Ленивые вычисления
Lua вычисляет логические выражения лениво: как только результат очевиден — вычисление прекращается.
- В
A and B: если A ложно — B даже не оценивается (результат уже ложен)
- В
A or B: если A истинно — B даже не оценивается (результат уже истинен)
Это важно, когда вторая часть может вызвать ошибку:
-- Если users[id] не существует — обращение к .name вызовет ошибку
-- Но благодаря ленивым вычислениям, если users[id] == nil (ложь),
-- правая часть не выполняется:
local user = users[id]
if user ~= nil and user.isActive then
print("Пользователь активен: " .. user.name)
end
-- Аналогично: сначала проверяем, что файл существует
-- Только потом читаем его размер
if file ~= nil and file.size > 0 then
processFile(file)
end
or для значений по умолчанию
Lua возвращает не просто true/false, а само значение из выражения. Это позволяет использовать or для задания значений по умолчанию:
local function greet(name)
name = name or "Гость"
print("Привет, " .. name .. "!")
end
greet("Никита") -- Привет, Никита!
greet() -- Привет, Гость!
local config = {}
local timeout = config.timeout or 30 -- если не задан — 30 секунд
local retries = config.retries or 3 -- если не задан — 3 попытки
local logLevel = config.logLevel or "info"
local function connect(host, port)
port = port or 80 -- стандартный HTTP порт по умолчанию
print("Подключение к " .. host .. ":" .. port)
end
connect("example.com") -- Подключение к example.com:80
connect("example.com", 443) -- Подключение к example.com:443
Практические примеры
Валидация формы регистрации:
local username = "nikita"
local password = "qwerty123"
local email = "test@mail.ru"
local age = 15
local isValid = username ~= ""
and password ~= ""
and email ~= ""
and age >= 13
if isValid then
print("Регистрация успешна")
else
print("Заполни все поля корректно")
end
Логика прав доступа:
local role = "editor"
local resourceType = "article"
local canRead = role == "viewer" or role == "editor" or role == "admin"
local canEdit = role == "editor" or role == "admin"
local canDelete = role == "admin"
if canEdit and resourceType == "article" then
print("Редактируем статью")
end
Проверка данных перед сохранением:
local function saveData(data)
if data == nil or data == "" then
print("Ошибка: данные пустые")
return false
end
if not (type(data) == "string" or type(data) == "number") then
print("Ошибка: неверный тип данных")
return false
end
-- всё в порядке
print("Данные сохранены: " .. tostring(data))
return true
end
🚀 Задания
Задание 1
Создай переменные: hasAccount (bool), isVerified (bool), trialExpired (bool). Напиши условие: пользователь может войти только если у него есть аккаунт И он верифицирован И пробный период не истёк.
Задание 2
Напиши валидатор пароля: пароль должен быть длиннее 7 символов (#password > 7), не равен "password" и не равен "123456". Используй and и not.
Задание 3
Напиши функцию isWeekday(day), которая принимает строку с днём недели и возвращает true, если это рабочий день (не суббота и не воскресенье). Используй not и and.
Задание 4
Напиши функцию getTimeout(config), которая принимает таблицу с настройками. Если config.timeout задан — используй его, иначе по умолчанию 5000 миллисекунд. Используй паттерн or.
Задание 5
Определи без запуска кода, что выведет программа, и объясни почему:
local x = nil
local y = false
local z = 0
if x or y or z then
print("Хотя бы одно истинно")
else
print("Все ложны")
end