Защищенные вызовы с 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() перехватывает её. Программа продолжает работу и может корректно обработать ошибку, проверив значение состояния.
Задание
ЛегкоНапишите функцию 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)
-- Напишите код здесь
-- Note: вызовите error(message, 0), чтобы Lua не добавлял имя файла и
-- номер строки перед вашим сообщением.
endВ этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Продвинутая итерация таблиц
Итерация с помощью pairs()Итерация с помощью ipairs()pairs() против ipairs()Повторение — Лист персонажа2Дополнительные функции библиотеки table
table.concat()Создание таблиц и unpack()table.sort()Пользовательская сортировка с помощью функцийИтоги — Таблица рекордовПотренируйтесь самостоятельно: Онлайн-компилятор Lua