Niektóre języki programowania, takie jak np. Scala, mają pojęcie Option
typów (zwanych także Maybe
), które mogą zawierać wartość lub nie.
Z tego, co o nich czytałem, są one powszechnie uważane za lepszy sposób radzenia sobie z tym problemem niż null
, ponieważ wyraźnie zmuszają programistę do rozważenia przypadków, w których może nie być żadnej wartości zamiast po prostu wysadzenia w powietrze w czasie wykonywania.
Z drugiej strony sprawdzone wyjątki w Javie wydają się być złym pomysłem, a Java wydaje się być jedynym powszechnie używanym językiem, który je implementuje. Ale idea za nimi wydaje się być nieco podobna do Option
typu, aby wyraźnie zmusić programistę do radzenia sobie z faktem, że może zostać zgłoszony wyjątek.
Czy są jakieś dodatkowe problemy z zaznaczonymi wyjątkami, Option
których nie mają typy? Czy te pomysły nie są tak podobne, jak myślę, i istnieją uzasadnione powody, aby wymuszać jawną obsługę Opcji, a nie wyjątków?
źródło
Either e a
typ danych.Odpowiedzi:
Ponieważ
Option
s są składalne. Istnieje wiele przydatnych metod naOption
które pozwalają pisać kod zwięzły, a jednocześnie pozwala na precyzyjne sterowanie przepływem:map
,flatMap
,toList
,flatten
i więcej. Wynika to z faktu, żeOption
jest to szczególny rodzaj monady, niektórych obiektów, które wiemy bardzo dobrze, jak komponować. Jeśli nie posiadałeś tych metod i musiałeś zawsze dopasowywać wzórOption
lubisDefined
często dzwonić , nie byłyby one tak przydatne.Zamiast tego, chociaż zaznaczone wyjątki zwiększają bezpieczeństwo, niewiele można z nimi zrobić, poza złapaniem ich lub pozwoleniem, by wybrzuszały się w stosie (z dodaną płytką kotłową w deklaracji typu).
źródło
try {/* bunch of complex code involving calls to 50 different methods that may throw SomeCheckedException */} catch(SomeCheckedException e) {/* operation failed, do something */}
ifromMaybe someDefaultValue (something >>= otherThing >>= ...50 other functions that may return Nothing...)
co dokładnie? Poza tym, że ten pierwszy zawiera więcej szczegółów na temat tego, co poszło nie tak.Chociaż są powiązane, wyjątki i być może obiekty nie dotyczą tego samego rodzaju problemów.
Wyjątki
Wyjątki naprawdę świecą, gdy musisz poradzić sobie z sytuacją wyjątkową (niekiedy lokalną). Na przykład analizujesz plik csv i chcesz zabezpieczyć się przed liniami z niewłaściwym formatowaniem. Miejscem, w którym zauważysz, że coś jest nie tak, mogą być niektóre wywołania funkcji z dala od iteracji linii. Jeśli rzucisz wyjątek na najgłębszym poziomie (gdzie dowiesz się o problemach z formatowaniem), możesz złapać go w pętli, zarejestrować błąd i przejść do następnego wiersza. Nie musisz niczego modyfikować w pozostałej części kodu.
Sprawdzony wyjątek powoduje wiele bólu, ponieważ wszystkie funkcje pośrednie muszą zadeklarować typ rzucalny. Funkcja pokonuje pierwotny cel, dlatego nie są obecnie popularne.
Może przedmioty
Może obiekty powinny być wybierane, gdy jesteś w stanie poradzić sobie lokalnie z „niepowodzeniem”. W tym sensie zastępują one kod powrotu + przekazanie przez interfejs API lub typ zerowy.
Zaletą obiektu Może jest to, że wyraźnie deklarujesz, że coś może być nie tak. W haskell obiekt, który może nie jest, musi mieć wartość, w przeciwnym razie program się nie skompiluje.
Problem z typami zerowalnymi polega na tym, że musisz cały czas sprawdzać wartość null, aby być całkowicie bezpiecznym. Domyślnym stanem jest „coś może być nie tak”.
Problem z kodami powrotu + przekazywaniem przez ap api polega na tym, że są one mniej czytelne dla większości ludzi.
źródło
ponieważ dzięki
Maybe
niemu możesz opóźnić obsługę błędu, aż faktycznie potrzebujesz wartości (może to być kilka wywołań metody)podczas gdy sprawdzony wyjątek musi być obsługiwany w miejscu połączenia
jedyną zaletą wyjątków jest to, że można przekazać więcej informacji na temat przyczyny niepowodzenia (chyba że ktoś opracuje pole
MaybeError
z możliwością rzucania, gdy jest to błąd)źródło
Maybe
typów z błędami obsługi. Do zgłoszenia błędu używany jest wyjątek, typ opcji służy do przedstawienia wyniku funkcji częściowej. Częściowe zwracanie funkcjiNothing
nie jest błędem.