
Я обнаружил, что это довольно понятно и в то же время непонятно, - это отсутствие статей, примеров или всего, что упоминало бы, как обрабатывать исключение в 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. Вот и вся причина, по которой я написал это. Не стесняйтесь оставлять мне любые комментарии или предложения. Спасибо!