Исключения
Исключения — это всего лишь специальный вид вариант, выбрасываемый в исключительных случаях (не злоупотребляйте ими).
Использование
let getItem = (theList) =>
if (callSomeFunctionThatThrows()) {
/* return the found item here */
} else {
raise(Not_found)
};
let result =
try (getItem([1, 2, 3])) {
| Not_found => 0 /* Default value if getItem throws */
};
Note that the above is just for demonstration purposes; in reality, you'd return an option(int)
directly from getItem
and avoid the try
altogether.
You can directly match on exceptions while getting another return value from a function:
switch (List.find((i) => i === theItem, myItems)) {
| item => print_endline(item)
| exception Not_found => print_endline("No such item found!")
};
Вы можете создавать ваши собственные исключения так же как создаете варианты (исключения также должны начинаться с заглавной буквы).
exception InputClosed(string);
...
raise(InputClosed("the stream has closed!"));
Советы и трюки
Так как у вас есть варианты, а обычно не нужны исключения. Например, вместо выбрасывания исключения, когда элемент item
не найден в коллекции, просто верните option(item)
(None
в случае когда не найдено).
Проектные решения
Совет выше выглядит противоречием тому, что происходит в стандартной библиотеке OCaml. Функции в модулях List и String часто выбрасывают исключения. Это сделано по историческим причинам и часто в угоду производительности. Нативный код OCaml/Reason очень производителен и исключения сделаны так, чтобы быть дешевле для алокации и выбрасывания чем option
. Для JavaScript это не так.
Новые альтернативы стандартной библиотеке обычно используют возврат option
вместо выбрасывания исключений. For example, List.find
has the option
-returning counterpart List.find_opt
, which doesn't throw.
Exceptions are actually just variants too. In fact, they all belong to a single variant type, called exn
. It's an extensible variant, meaning you can add new constructors to it, such as InputClosed
above. exception Foo
is just a sugar for adding a constructor to exn
.