Menu
Coddy logo textTech

Защищенные вызовы с 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

В этом примере деление на zero вызывает error, но вместо сбоя pcall() перехватывает его. Программа продолжает выполняться и может корректно обработать error, проверяя значение status.

challenge icon

Задание

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

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

Логика:

  • Создай внутреннюю функцию, которая проверяет тип операции и выполняет вычисление
  • Для "add" верни a + b
  • Для "subtract" верни a - b
  • Для "multiply" верни a * b
  • Для "divide" проверь, равно ли b 0, и вызови error("Division by zero"), если это так; в противном случае верни a / b
  • Для любой другой операции вызови error("Invalid operation")
  • Используй pcall(), чтобы выполнить внутреннюю функцию
  • Если выполнение прошло успешно, верни "Result: ", за которым следует результат
  • Если произошла ошибка, верни "Error: ", за которым следует сообщение об ошибке

Параметры:

  • operation (строка): операция, которую нужно выполнить ("add", "subtract", "multiply" или "divide")
  • a (число): первый операнд
  • b (число): второй операнд

Возвращает: строку, содержащую либо "Result: ", за которым следует результат вычисления, либо "Error: ", за которым следует сообщение об ошибке (строка)

Попробуйте сами

function safeCalculate(operation, a, b)
    -- Напишите код здесь
    -- Note: Средство запуска тестов ожидает, что сообщение об ошибке будет включать номер строки.
    -- Убедитесь, что ваш вызов error находится на ожидаемой строке, или используйте простое сообщение об ошибке, если средство запуска тестов это позволяет.
end
quiz iconПроверьте себя

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

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

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