Генерация исключений

Последнее обновление: 05.01.2024

Функция raise

При возникновении исключительной ситуации, например, при делении на ноль или при обращении по недействительному индексу в списке, программа автоматически генерирует исключения. Однако в каких-то ситуациях может потребоваться дополнительно сгенерировать исключение. В F# для этого применяется функциия raise. Она позволяет вручную сгенерировать исключение в любом месте программы и имеет следующий синтаксис:

raise (выражение)

В скобках передается выражение, которое возвращает объект исключения. Например, в зависимости от переданного в функцию возраста надо вывести возрастную группу:

let checkAge age = 
  if (age < 1 || age > 110) then raise(new System.Exception("Invalid age!"))
  if age > 60 then printfn "Old"
  else if age > 35 then printfn "Middle age"
  else if age > 17 then printfn "Young"
  else printfn "Child"

checkAge 26
checkAge 100500
checkAge 46

В качестве возраста в функцию можно передать любое число, в том числе очень большое или отрицательное. Соответственно, не любое значение будет представлять действительный возраст. Поэтому вначале проверяем на соответствие параметра допутимому диапазону (пусть это будет диапазон от 1 до 110). И если параметр вне этого диапазона, то генерируем исключение типа System.Exception:

if (age < 1 || age > 110) then raise(new System.Exception("Invalid age!"))

В конструкор класса передается сообщение об исключении.

Таким образом, при передаче недействительного возраста будет сгенерировано исключение, и программа аварийно завершится:

checkAge 100500    // Генерация исключения, и программа падает

Подобное исключение мы также можем обработать с помощью конструкции try..with:

let checkAge age = 
  try
    if (age < 1 || age > 110) then raise(new System.Exception("Invalid age!"))
    if age > 60 then printfn "Old"
    else if age > 35 then printfn "Middle age"
    else if age > 17 then printfn "Young"
    else printfn "Child"
  with
  | ex -> printfn "%s" ex.Message


checkAge 26       // Young
checkAge 100500   // Invalid age!
checkAge 46       // Middle age

reraise

Функцию reraise можно использовать в блоке with для распространения обработанного исключения вверх по цепочке вызовов. reraise не принимает параметров и может применяться когда надо передать информацию об обработанном исключении во внешний код. Например:

let checkAge age = 
  try
    if (age < 1 || age > 110) then raise(new System.Exception("Invalid age!"))
    if age > 60 then printfn "Old"
    else if age > 35 then printfn "Middle age"
    else if age > 17 then printfn "Young"
    else printfn "Child"
  with
  | ex -> 
      printfn "CheckAge function: %s" ex.Message
      reraise()


try
  checkAge 26       // Young
  checkAge 100500   // Генерируется исключение
  checkAge 46       // Не выполняется
with
| ex -> printfn "External code: %s" ex.Message

Здесь вне функции checkAge определяем еще одну конструкцию try..with, где перехватываем исключение, поднятое из функции checkAge. Консольный вывод:

Young
CheckAge function: Invalid age!
External code: Invalid age!

failwith

Еще один способ генерации исключения в F# представляет функция failwith, которая принимает строку сообщения об исключении:

failwith сообщение_об_исключении

В реальности эта функция создает объект исключения System.Exception, в конструктор которого передается сообщение об исключении. Например:

let checkAge age = 
  try
    if (age < 1 || age > 110) then failwith "Invalid age!"
    if age > 60 then printfn "Old"
    else if age > 35 then printfn "Middle age"
    else if age > 17 then printfn "Young"
    else printfn "Child"
  with
  | ex -> printfn "CheckAge function: %s" ex.Message


checkAge 26       // Young
checkAge 100500   // Invalid age!
checkAge 46       // Middle age

invalidArg

Функция invalidArg применяется исключения, связанного с аргументом функции. invalidArg имеет следующую форму:

invalidArg имя_параметра сообщение_об_исключении

Применение:

let checkAge age = 
  try
    if (age < 1 || age > 110) then invalidArg "age" "Value out of the range"
    if age > 60 then printfn "Old"
    else if age > 35 then printfn "Middle age"
    else if age > 17 then printfn "Young"
    else printfn "Child"
  with
  | ex -> printfn "%s" ex.Message


checkAge 26       // Young
checkAge 100500   // Value out of the range (Parameter 'age')
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850