Я обнаружил, что это довольно понятно и в то же время непонятно, - это отсутствие статей, примеров или всего, что упоминало бы, как обрабатывать исключение в ReasonML. По своей природе я не вижу особого использования кода записи исключений в ReasonML. Однако этого нельзя избежать, когда мы хотим взаимодействовать с JavaScript.
Поскольку я не могу найти формальную грамматику исключения ReasonML, я вернусь к определению исключение OCaml.
в Ocaml Exception - это просто расширяемый вариант типа
exn
Чтобы обработать исключение в OCaml, мы можем использовать конструкцию try/with
, которая напоминает сопоставление с шаблоном:
try <expr> with | <pat1> -> <expr1> | <pat2> -> <expr2> ...
В ReasonML мы используем следующее предложение:
try (<expr>) { | <pat1> => <expr1> | <pat2> => <expr2> ... }
expr
оценивается и проверяется. Если возникает исключение, оно пытается сопоставить данный шаблон (помните, что это обычное сопоставление с шаблоном с ограничением встроенного типа exn
). В противном случае результатом будет оценка expr
. Следующий код - это пример того, как использовать исключение в синтаксисе ReasonML.
try (f) { | SomeExn => doSomething() | AnotherExn(value) => doSomethingWith(value) ... }
Шаблон в предложении должен быть только типа exn
. Позже мы покажем, что это ключевое слово можно заменить на switch
типа исключения.
Определите тип исключения, используя ключевое слово exception
Чтобы работать с исключениями, мы должны сначала знать, как их определить. Это просто, как определить тип. Фактически, exception
- это синтаксический сахар для добавления нового типа в exn.
. Рассмотрим следующий код:
type exn += | MyError; exception MyAnotherError;
Первые две строки предназначены для добавления нового типа с именем MyError
с использованием синтаксиса расширяемого варианта. Строка ниже делает то же самое, но с использованием ключевого слова exception
. Как мы видим из аналога JavaScript:
var MyError = Caml_exceptions.create("MyError"); var MyAnotherError = Caml_exceptions.create("MyAnotherError");
exception
Определение - это определение любого исключения, которое мы хотим придать смысл нашей программе. Однако, чтобы иметь дело с исключениями из JavaScript, мы должны обрабатывать Js.Exn.Error(t)
Обработка исключения со стороны JavaScript
Большинство исключений, поднятых со стороны JavaScript, станут значениями типа Js.Exn.Error(t)
. Предположим, что в сценарии мы хотим использовать функцию JavaScript, которая может генерировать исключение.
exports.func = function(x) { throw new Error("My Js Error"); return x; }
Нам нужно правильно обработать это исключение.
[@bs.module "./test.js"] external func: (string) => string = "func"; let result = try(func("test"){ |Js.Exn.Error(err) => Js.Exn.message(err) |> Js.Option.getWithDefault("Some Js Error");"" |x => failwith(x);"Other Error" }
Приведенный выше код импортирует functionfunc
, который является функцией JavaScript, и использует конструкцию try
, чтобы проверить, вызывает ли она исключение. Если выбрано исключение типа Js.Exn.Error
, мы будем использовать Js.Exn.message
для извлечения сообщения об ошибке. В противном случае будут failwith
исключения любого другого типа.
Обратите внимание, что результат try
должен быть того же типа, что и результат func
, в данном случае string
.
Чтобы понять, почему, давайте развернем try
до нормального сопоставления с образцом. Мы можем добиться того же поведения, используя сопоставление с образцом следующим образом:
[@bs.module "./test.js"] external func: (string) => string = "func"; let result = switch(func("test")){ | exception(Js.Exn.Error(err)) => Js.Exn.message(err) |> Js.Option.getWithDefault("Some Js Error");"" | exception(x) => failwith(x);"Other Error" | value => value }
Теперь все имеет больше смысла, потому что value => value
предполагает, что тип этой оценки должен возвращать value
типа func
результата.
Надеюсь, это будет полезно, когда вы пытаетесь использовать Google для обработки исключений ReasonML. Вот и вся причина, по которой я написал это. Не стесняйтесь оставлять мне любые комментарии или предложения. Спасибо!