Exception
Exceptions sind nur eine spezielle Art der Varianten, die in exzeptionellen Fällen „geworfen“ werden (missbrauche sie nicht!).
Verwendung
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 */
};
Beachte dass obiges nur für Demonstrationszwecke steht. In Wirklichkeit würdest du ein option(int)
direkt aus getItem
zurückgeben und try
gänzlich vermeiden.
Du kannst Pattern Matching direkt auf Exceptions anwenden während ein anderer Rückgabewert einer Funktion erhalten wird:
switch (List.find((i) => i === theItem, myItems)) {
| item => print_endline(item)
| exception Not_found => print_endline("No such item found!")
};
Du kannst auch deine eigenen Exceptions erzeugen, so wie du eine Variante erstellen würdest (Exceptions müssen auch groß geschrieben werden).
exception InputClosed(string);
...
raise(InputClosed("the stream has closed!"));
Tips & Tricks
Wenn du gewöhnliche Varianten hast, brauchst du oft keine Exceptions. Zum Beispiel, anstatt eine Exception zu werfen, wenn item
nicht in einer Collection gefunden werden kann, versuche stattdessen ein option(item)
(None
in diesem Fall) zurückzugeben.
Designentscheidungen
Der obige Tip scheint dem zu widersprechen, was in der der OCaml Standardbibliothek geschieht. Prominente Funktionen in Modulen wie Liste und String scheinen übermäßig häufig Exceptions auszulösen. Dies ist teilweise ein historisches Sediment und teilweise aus extremer Sorgfalt für die Performance begründet. Natives OCaml/Reason ist unglaublich performant. Exceptions auszulösen wurde so entwickelt, dass es sehr günstig ist, güntiger als z. B. ein option
zu erzeugen und zurückzugeben. Dies ist leider nicht der Fall in JavaScript.
Neuere Alternativen der Standardbibliothek kommen normalerweise mit Funktionen, die option
zurückliefern, und keine Exceptions auslösen. Zum Beispiel hat List.find
die option
-Rückgabe-Entsprechung List.find_opt
, die keine Exceptions auslöst.
Exceptions sind tatsächlich auch Varianten. Tatsächlich gehören sie alle zu einem einzigen Variantentyp namens exn
. Es ist eine erweiterbare Variante, was bedeutet, dass du ihr neue Konstruktoren hinzufügen kannst, so wie InputClosed
oben. exception Foo
ist lediglich syntaktischer Zucker, um einen Konstruktor zu exn
hinzuzufügen.