Dopiero zaczynam z Go. Mój kod zaczyna mieć dużo tego:
if err != nil {
//handle err
}
albo to
if err := rows.Scan(&some_column); err != nil {
//handle err
}
Czy są jakieś dobre idiomy / strategie / najlepsze praktyki dotyczące sprawdzania i obsługi błędów w Go?
EDYTUJ, aby wyjaśnić: nie oszukuję ani nie sugeruję, aby zespół Go wymyślił coś lepszego. Pytam, czy robię to dobrze, czy też przegapiłem jakąś technikę wymyśloną przez społeczność. Dziękuje wszystkim.
Odpowiedzi:
Twój kod jest idiomatyczny i moim zdaniem jest to najlepsza dostępna praktyka. Niektórzy na pewno by się z tym nie zgodzili, ale ja argumentowałbym, że jest to styl widoczny we wszystkich standardowych bibliotekach w Golangu . Innymi słowy, autorzy Go piszą w ten sposób obsługę błędów.
źródło
Sześć miesięcy po zadaniu tego pytania Rob Pike napisał post na blogu zatytułowany Błędy to wartości .
W tym miejscu argumentuje, że nie trzeba programować w sposób przedstawiony przez PO i wspomina o kilku miejscach w bibliotece standardowej, w których używają innego wzorca.
To dobra lektura.
źródło
Zgodziłbym się z odpowiedzią jnml, że oba są kodem idiomatycznym i dodam:
Twój pierwszy przykład:
jest bardziej idiomatyczny, gdy mamy do czynienia z więcej niż jedną wartością zwracaną. na przykład:
Twój drugi przykład jest fajnym skrótem, jeśli chodzi tylko o
err
wartość. Ma to zastosowanie, jeśli funkcja zwraca tylko wartość anerror
lub celowo zignorujesz zwrócone wartości inne niżerror
. Na przykład jest to czasami używane z funkcjamiReader
i,Writer
które zwracająint
liczbę zapisanych bajtów (czasami niepotrzebne informacje) orazerror
:Drugi formularz jest określany jako użycie instrukcji inicjalizacji if .
Jeśli chodzi o najlepsze praktyki, o ile wiem (z wyjątkiem używania pakietu „errors” do tworzenia nowych błędów, gdy ich potrzebujesz), omówiłeś prawie wszystko, co musisz wiedzieć o błędach w Go!
EDIT: Jeśli okaże się, naprawdę nie mogą żyć bez wyjątków, można naśladować ich
defer
,panic
irecover
.źródło
Stworzyłem bibliotekę do usprawnionej obsługi błędów i przesyłania przez kolejkę funkcji Go.
Możesz go znaleźć tutaj: https://github.com/go-on/queue
Ma zwarty i pełny wariant składni. Oto przykład krótkiej składni:
Należy pamiętać, że istnieje niewielki narzut wydajności, ponieważ wykorzystuje refleksję.
Nie jest to również idiomatyczny kod go, więc będziesz chciał go używać we własnych projektach lub jeśli Twój zespół zgodzi się go używać.
źródło
„Strategią” obsługi błędów w języku golang i innych językach jest ciągłe rozpowszechnianie błędów w stosie wywołań, dopóki nie osiągniesz wystarczająco wysokiego poziomu w stosie wywołań, aby obsłużyć ten błąd. Jeśli próbowałeś obsłużyć ten błąd zbyt wcześnie, prawdopodobnie w końcu powtórzysz kod. Jeśli poradzisz sobie z tym za późno, zepsujesz coś w swoim kodzie. Golang sprawia, że ten proces jest bardzo łatwy, ponieważ bardzo jasno określa, czy obsługujesz błąd w danej lokalizacji, czy też go propagujesz.
Jeśli zamierzasz zignorować błąd, proste _ ujawni ten fakt bardzo wyraźnie. Jeśli go obsługujesz, to dokładnie, który przypadek błędu, który obsługujesz, jest jasny, ponieważ sprawdzisz go w instrukcji if.
Jak ludzie powiedzieli powyżej, błąd jest w rzeczywistości zwykłą wartością. To traktuje to jako takie.
źródło
Bogowie Go opublikowali "szkic projektu" do obsługi błędów w Go 2. Ma on na celu zmianę idiomu błędów:
Przegląd i projekt
Chcą opinii użytkowników!
Witryna wiki opinii
W skrócie wygląda to tak:
AKTUALIZACJA: Projekt projektu spotkał się z dużą krytyką, dlatego przygotowałem projekt Wymagania do rozważenia w przypadku obsługi błędów Go 2 z menu możliwości ewentualnego rozwiązania.
źródło
Większość w branży postępuje zgodnie ze standardowymi zasadami wymienionymi w dokumentacji firmy Golang. Obsługa błędów i gotowe . Pomaga także w generowaniu dokumentów dla projektu.
źródło
Poniżej znajduje się moja opinia na temat ograniczenia obsługi błędów w Go, przykład dotyczy pobierania parametrów adresu URL HTTP:
(Wzorzec projektowy pochodzi z https://blog.golang.org/errors-are-values )
wywołanie go dla wielu możliwych parametrów wyglądałoby następująco:
To nie jest srebrna kula, wadą jest to, że jeśli miałeś wiele błędów, możesz uzyskać tylko ostatni błąd.
Ale w tym przypadku jest to stosunkowo powtarzalne i niskie ryzyko, dlatego mogę uzyskać ostatni możliwy błąd.
źródło
Państwo może oczyścić swój kod obsługi błędów dla podobnych błędów (ponieważ błędy są wartościami trzeba być ostrożnym tutaj) i napisać funkcję, którą nazywasz z błędem przeszedł do obsługi błędu. Nie będziesz wtedy musiał za każdym razem pisać "if err! = Nil {}". Ponownie, spowoduje to jedynie wyczyszczenie kodu, ale nie sądzę, że jest to idiomatyczny sposób robienia rzeczy.
Ponownie, tylko dlatego, że możesz , nie oznacza, że powinieneś .
źródło
goerr umożliwia obsługę błędów za pomocą funkcji
źródło
Jeśli chcesz precyzyjnej kontroli błędów, może nie jest to rozwiązanie, ale dla mnie w większości przypadków każdy błąd jest zatrzymaniem pokazu.
Więc zamiast tego używam funkcji.
źródło
stderr
raczej do niżstdout
, więc po prostu użyjlog.Fatal(err)
lublog.Fatalln("some message:", err)
. Ponieważ prawie nic pozamain
podjęciem takiej decyzji o zakończeniu całego programu (tj. Zwrócenie błędów z funkcji / metod, nie przerywaj) w rzadkich przypadkach jest to, co chcesz zrobić, jest to czystsze i lepiej zrobić to jawnie (tj.if err := someFunc(); err != nil { log.Fatal(err) }
), a nie poprzez funkcję „pomocniczą”, która nie jest jasna co do tego, co robi (nazwa „Err” nie jest dobra, nie daje żadnej wskazówki, że może zakończyć program).