Исключения непосредственно языка F# несколько отличаются от общей системы типов исключений .NET. Так, для определения исключения F# применяется следующий синтаксис:
exception имя_исключения of список_аргументов
После оператора exception идет имя объявляемого типа исключения. А после слова of указывается список аргументов исключения.
Например, простейшее определение исключения:
exception MyError of string
В данном случае тип исключения называется MyError, и он принимает один аргумент типа string, то есть строку.
Подобные типы можно использовать при генерации исключений, например, с помощью оператора raise:
exception MyError of string let checkAge age = try if (age < 1 || age > 110) then raise (MyError ("Invalide 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 | MyError(mes) -> printfn "%s" mes checkAge 26 // Young checkAge 100500 // Invalide age checkAge 46 // Middle age
Здесь функция checkAge
через параметр age принимает некоторое значение возраста и в зависимости от этого значения выводит определенную строку.
Однако переданное число потенциально может хранить вообще любое числовое значение, в том числе и отрицательное или очень большое значение, которое может быть вне допустимого диапазона возрастов.
В данном случае это диапазон от 1 до 110. И если переданное значение вне этого диапазона, то генерируем ошибку типа MyError, передавая ей некоторое сообщение:
if (age < 1 || age > 110) then raise (MyError ("Invalide age"))
В конструкции try..with
в блоке with мы можем сопоставить с типом ошибки и получить переданное сообщение:
with | MyError(mes) -> printfn "%s" mes
При необходимости мы можем определить ошибку с большим количеством аргументов:
exception MyError of string*int let checkAge age = try if (age < 1 || age > 110) then raise (MyError ("Invalide age", 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 | MyError(mes, value) -> printfn "%s (%d)" mes value checkAge 26 // Young checkAge 100500 // Invalide age (100500) checkAge 46 // Middle age
Количество типов аргументов в определении типа ошибки определяет количество передаваемых в ошибку аргументов. Друг от друга типы отделяются символом звездочки:
exception MyError of string*int
То есть в данном случае ошибка MyError принимает два аргумента. Первый представляет строку, а второй - число типа int.
При генерации ошибке ей соответственно передается два значения:
if (age < 1 || age > 110) then raise (MyError ("Invalide age", age))
В данном случае второй аргумент - некорректное значение возраста.
В блоке with оба аргумента также можно получить с помощью сопоставления паттернов:
with | MyError(mes, value) -> printfn "%s (%d)" mes value
В данном случае второй аргумент передается в значение value и затем выводится на консоль вместе с сообщением об ошибке.