Защищенные вызовы с pcall()
Часть раздела Логика и управление потоком путешествия по Lua на Coddy. Урок 33 из 54.
Хотя error() останавливает программу, когда что-то идет не так, иногда нужно обрабатывать ошибки, не допуская аварийного завершения. Функция pcall() в Lua позволяет безопасно выполнять код, который может завершиться с ошибкой.
Название pcall() означает «защищённый вызов». Оно оборачивает вызов функции в защитный слой, который перехватывает любые ошибки. Вместо того чтобы программа аварийно завершилась, pcall() возвращает информацию о том, что произошло.
Вот базовый синтаксис:
local status, result = pcall(functionName, arg1, arg2)Функция pcall() возвращает два значения. Первое — логический статус: true, если функция выполнилась успешно, или false, если произошла ошибка. Второе значение зависит от статуса: при успешном выполнении это возвращаемое функцией значение; если произошла ошибка — сообщение об ошибке.
Вот практический пример:
function divide(a, b)
if b == 0 then
error("Cannot divide by zero")
end
return a / b
end
local success, result = pcall(divide, 10, 0)
if success then
print("Result: " .. result)
else
print("Error caught: " .. result)
endВ этом примере деление на ноль вызывает ошибку, но вместо аварийного завершения программы её перехватывает pcall(). Программа продолжает работу и может корректно обработать ошибку, проверив значение статуса.
Имей в виду, что pcall() перехватывает все ошибки внутри вызова, включая неожиданные ошибки в коде, и сообщает о них одинаково. Поэтому оборачивай только вызов, который может завершиться ошибкой, а для ожидаемых ошибок предпочитай функцию, которая возвращает nil и сообщение, как в предыдущем уроке.
Задание
ЛегкоНапиши функцию safeCalculate, которая принимает operation, a и b и возвращает результат вычисления или сообщение об ошибке.
Функция должна использовать pcall(), чтобы безопасно выполнить запрошенную математическую операцию. Создай внутреннюю функцию, которая выполняет вычисление в зависимости от строки операции, а затем оберни её в pcall(), чтобы перехватывать ошибки.
Логика:
- Создай внутреннюю функцию, которая проверяет тип операции и выполняет вычисление
- Для "add" верни
a + b - Для "subtract" верни
a - b - Для "multiply" верни
a * b - Для "divide" проверь, равен ли
b0, и вызовиerror("Division by zero", 0), если это так; в противном случае верниa / b - Для любой другой операции вызови
error("Invalid operation", 0) - Используй
pcall(), чтобы выполнить внутреннюю функцию - Если выполнение прошло успешно, верни
"Result: ", за которым следует результат - Если произошла ошибка, верни
"Error: ", за которым следует сообщение об ошибке
Передай 0 в качестве второго аргумента error(). Этот аргумент задаёт уровень ошибки, а 0 указывает Lua не добавлять имя файла и номер строки перед сообщением, поэтому возвращаемая строка будет точно равна "Error: Division by zero".
Параметры:
operation(строка): операция для выполнения ("add", "subtract", "multiply" или "divide")a(число): первый операндb(число): второй операнд
Возвращаемое значение: строка, содержащая либо "Result: ", за которым следует результат вычисления, либо "Error: ", за которым следует сообщение об ошибке (строка)
Попробуйте сами
function safeCalculate(operation, a, b)
-- Напишите код здесь
-- Примечание: вызовите error(message, 0), чтобы Lua не добавлял имя файла и
-- номер строки перед вашим сообщением.
endВ этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Продвинутая итерация таблиц
Итерация с помощью pairs()Итерация с помощью ipairs()pairs() против ipairs()Повторение — Лист персонажа2Дополнительные функции библиотеки table
table.concat()Создание таблиц и unpack()table.sort()Пользовательская сортировка с помощью функцийИтоги — Таблица рекордовПотренируйтесь самостоятельно: Онлайн-компилятор Lua