Menu
CoddyTech

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

challenge icon

Задание

Легко

Напишите функцию safeCalculate, которая принимает operation, a и b и возвращает результат вычисления или сообщение об ошибке.

Функция должна использовать pcall() для безопасного выполнения запрошенной математической операции. Создайте внутреннюю функцию, которая выполняет вычисление на основе строки операции, а затем оберните её в pcall(), чтобы перехватывать любые ошибки.

Логика:

  • Создайте внутреннюю функцию, которая проверяет тип операции и выполняет вычисление
  • Для "add" верните a + b
  • Для "subtract" верните a - b
  • Для "multiply" верните a * b
  • Для "divide" проверьте, равен ли b 0, и вызовите 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
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком

Потренируйтесь самостоятельно: Онлайн-компилятор Lua