Защищенные вызовы с pcall()
Часть раздела Логика и управление потоком путешествия по Lua на Coddy — урок 33 из 54.
Хотя error() останавливает вашу программу, когда что-то идет не так, иногда вам нужно обработать ошибки без сбоя. Функция Lua pcall() позволяет безопасно выполнять код, который может завершиться ошибкой.
Название pcall() означает "protected call" (защищенный вызов). Оно обертывает вызов функции защитным слоем, который перехватывает любые ошибки. Вместо того чтобы ваша программа аварийно завершалась, 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() перехватывает её. Программа продолжает работать и может корректно обработать ошибку, проверив значение status.
Задание
ЛегкоНапишите функцию safeCalculate, которая принимает operation, a и b и возвращает результат вычислений или сообщение об ошибке.
Функция должна использовать pcall() для безопасного выполнения запрошенной математической операции. Создайте внутреннюю функцию, которая выполняет вычисление на основе строки операции, а затем оберните её с помощью pcall() для перехвата любых ошибок.
Логика:
- Создайте внутреннюю функцию, которая проверяет тип операции и выполняет вычисление
- Для "add" верните
a + b - Для "subtract" верните
a - b - Для "multiply" верните
a * b - Для "divide" проверьте, равен ли
b0, и вызовитеerror("Division by zero"), если это так, иначе вернитеa / b - Для любой другой операции вызовите
error("Invalid operation") - Используйте
pcall()для выполнения внутренней функции - В случае успеха верните
"Result: ", за которым следует результат - Если возникла ошибка, верните
"Error: ", за которым следует сообщение об ошибке
Параметры:
operation(string): Выполняемая операция ("add", "subtract", "multiply" или "divide")a(number): Первый операндb(number): Второй операнд
Возвращаемое значение: Строка, содержащая либо "Result: ", за которым следует результат вычислений, либо "Error: ", за которым следует сообщение об ошибке (string)
Попробуйте сами
function safeCalculate(operation, a, b)
-- Напишите код здесь
-- Note: Тестовый раннер ожидает, что сообщение об ошибке будет включать номер строки.
-- Убедитесь, что ваш вызов error находится на ожидаемой строке, или используйте простое сообщение об ошибке, если тестовый раннер это позволяет.
endВ этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Продвинутая итерация таблиц
Итерация с помощью pairs()Итерация с помощью ipairs()pairs() против ipairs()Повторение — Лист персонажа2Дополнительные функции библиотеки table
table.concat()Создание таблиц и unpack()table.sort()Пользовательская сортировка с помощью функцийИтоги — Таблица рекордов