Tylko komentarz, który, miejmy nadzieję, pomoże w przyszłym czytaniu kodu Go: w wielu przykładowych kodach panicjest używany do kończenia pracy w przypadku błędu, wyłącznie dlatego, że jest łatwy do zrozumienia i eliminuje importowanie jakichkolwiek innych pakietów. To nie znaczy, że jest dobry, lub idiomatyczne praktykę! . To tylko urządzenie oszczędzające miejsce, na przykład kod. IRL rezerwuje panicna bardzo szczególne sytuacje.
Intermernet
2
Hm..good) zwłaszcza skrót "IRL" - to dla mnie nowość :) Czy możesz wyjaśnić, jak panika eliminuje importowanie paczek?
Timur Fayzrakhmanov
5
panicjest wbudowany. Zaleca się (zależnie od okoliczności), aby użyć czegoś podobnego os.Exit, log.Fatalitd., Która zwróci kod błędu do systemu operacyjnego (zalecane zawsze, jeśli to możliwe). Wszystko to obejmuje importowanie pakietu, a tym samym „zaśmiecanie” przykładowego kodu. Przykładowy kod powinien być zawsze używany tylko w celu zademonstrowania rozwiązania określonego problemu. Mogą istnieć inne problemy z kodem, które sprawiają, że kod jest bardziej złożony, jeśli jest odpowiednio zademonstrowany, a zatem utrudniają wyjaśnienie udzielonej odpowiedzi. YMMV.
Intermernet
1
Ok, rozumiem) Wielkie dzięki) widzę, że jest jeszcze inny skrót do mojego słownictwa :)!
Timur Fayzrakhmanov
2
NP, z przyjemnością pomogę i zwiększysz swój akronimiczny leksykon :-)
Intermernet,
Odpowiedzi:
85
Przede wszystkim, kiedy masz pytanie „jak to jest używane w praktyce”, dobrym sposobem na rozpoczęcie jest przeszukanie kodu źródłowego Go (lub dowolnej wystarczająco dużej bazy kodu Go, tak naprawdę) i dokumentacji pakietu w celu uzyskania odpowiedzi.
Teraz os.Exiti panicsą zupełnie inne. panicjest używany, gdy program lub jego część osiągnęły stan niemożliwy do odzyskania.
Gdy panicjest wywoływana, w tym niejawnie w przypadku błędów czasu wykonywania, takich jak indeksowanie wycinka poza granicami lub niepowodzenie potwierdzenia typu, natychmiast zatrzymuje wykonywanie bieżącej funkcji i rozpoczyna rozwijanie stosu goroutine, uruchamiając po drodze wszelkie odroczone funkcje. Jeśli to odwijanie osiągnie szczyt stosu gorutyny, program umiera.
os.Exitjest używany, gdy trzeba natychmiast przerwać program , bez możliwości przywrócenia lub wykonania odroczonej instrukcji czyszczenia, a także zwrócić kod błędu (który inne programy mogą wykorzystać do zgłoszenia tego, co się stało). Jest to przydatne w testach, gdy już wiesz, że po tym, jak jeden test się nie powiedzie, drugi również się nie powiedzie, więc równie dobrze możesz teraz po prostu zakończyć. Można tego również użyć, gdy program zrobił wszystko, co musiał, a teraz musi tylko zakończyć, tj. Po wydrukowaniu komunikatu pomocy.
W większości przypadków nie będziesz używać panic(powinieneś errorzamiast tego zwrócić ) i prawie nigdy nie potrzebujesz os.Exitpoza niektórymi przypadkami w testach i do szybkiego zakończenia programu.
„Jest to przydatne w testach, kiedy już wiesz, że po tym, jak jeden test się nie powiedzie, drugi również się nie powiedzie…” To pachnie testującym anty-wzorcem testów zależnych. W dobrze napisanym zestawie testów każdy test jest niezależny; wynik jakiegokolwiek testu nigdy nie powinien przesądzać o wyniku żadnego innego testu.
gotgenes
1
@gotgenes Niekoniecznie. Jeśli mam test, w którym określona funkcja zwraca strukturę różną od zera, a ten test się nie powiedzie, to mogę się spodziewać, że wszystkie testy sprawdzające wartości struktury również zakończą się niepowodzeniem. To kod jest zależny, a nie testy. (To powiedziawszy, nie użyłbym exitw tym przypadku, po prostu spodziewałbym się dużego stosu nieudanych asercji.)
David Moles
84
Przede wszystkim os.Exit()można go użyć do normalnego wyjścia z programu bez błędu i bez paniki, więc jest to jedna kluczowa różnica. Innym jest to, że gdzieś panikę można złapać i zignorować lub zarejestrować za pomocą recover.
Ale jeśli mówimy o błędnym kodzie wyjścia, powiedzmy:
Użyj, panicgdy coś pójdzie nie tak, prawdopodobnie błąd programisty, który powinien zostać wyłapany przed przejściem do produkcji. Dlatego drukuje stos.
Użyj os.Exit(errorCode)lub czegoś takiego, jeśli chcesz:
kontrolować kod zakończenia programu do celów skryptowych.
chcą uporządkowanego zakończenia w przypadku oczekiwanego błędu (np. błąd danych wejściowych użytkownika).
Zasadniczo panika jest dla ciebie, zły kod wyjścia jest dla twojego użytkownika.
„Więc generalnie panika jest dla ciebie, zły kod wyjścia dla twojego użytkownika”. <- Niesamowita wskazówka
psousa
1
Czy możemy powiedzieć, że panic () jest w jakiś sposób powiązane ze zwykłym wywołaniem assert () w zwykłym C? Cóż ... Wiem, że zawsze usuwam wywołanie potwierdzające przed przekazaniem do produkcji, włączam je tylko podczas testowania nowej funkcji. Chodzi mi o to, że przez większość czasu używam assert () do weryfikacji niezmienników, które, jak sądzę, muszą być prawdziwe w moim kodzie. Czy widzisz to samo użycie dla panic ()? :-)
yves Baumes
7
Kluczowe różnice to:
os.Exit pomija wykonanie odroczonej funkcji.
Za pomocą os.Exitmożna określić kod zakończenia.
panickończy, podczas gdy os.Exitnie jest. (Wydaje się, że inne odpowiedzi o tym nie wspominają.)
Jeśli chcesz wykonać odroczoną funkcję, nie masz innego wyjścia panic. (Z drugiej strony, jeśli chcesz pominąć wykonywanie funkcji odroczonej, użyj os.Exit.)
Jeśli funkcja nie pusta jest zdefiniowana w następujący sposób:
funkcja zawiera wiele gałęzi
wszystkie gałęzie są zakończone returnlubpanic
Wtedy nie możesz zamienić na, panicw os.Exitprzeciwnym razie kompilator odmówi kompilacji programu, mówiąc „brak powrotu na końcu funkcji”. (Go jest tutaj bardzo głupi, nawet log.Panicnie kończy funkcji).
W innych warunkach:
Użyj, panicgdy dzieje się coś naprawdę połączonego, np. Błąd logiki programowania.
Użyj, os.Exitgdy chcesz natychmiastowego wyjścia z określonym kodem zakończenia.
panic
jest używany do kończenia pracy w przypadku błędu, wyłącznie dlatego, że jest łatwy do zrozumienia i eliminuje importowanie jakichkolwiek innych pakietów. To nie znaczy, że jest dobry, lub idiomatyczne praktykę! . To tylko urządzenie oszczędzające miejsce, na przykład kod. IRL rezerwujepanic
na bardzo szczególne sytuacje.panic
jest wbudowany. Zaleca się (zależnie od okoliczności), aby użyć czegoś podobnegoos.Exit
,log.Fatal
itd., Która zwróci kod błędu do systemu operacyjnego (zalecane zawsze, jeśli to możliwe). Wszystko to obejmuje importowanie pakietu, a tym samym „zaśmiecanie” przykładowego kodu. Przykładowy kod powinien być zawsze używany tylko w celu zademonstrowania rozwiązania określonego problemu. Mogą istnieć inne problemy z kodem, które sprawiają, że kod jest bardziej złożony, jeśli jest odpowiednio zademonstrowany, a zatem utrudniają wyjaśnienie udzielonej odpowiedzi. YMMV.Odpowiedzi:
Przede wszystkim, kiedy masz pytanie „jak to jest używane w praktyce”, dobrym sposobem na rozpoczęcie jest przeszukanie kodu źródłowego Go (lub dowolnej wystarczająco dużej bazy kodu Go, tak naprawdę) i dokumentacji pakietu w celu uzyskania odpowiedzi.
Teraz
os.Exit
ipanic
są zupełnie inne.panic
jest używany, gdy program lub jego część osiągnęły stan niemożliwy do odzyskania.os.Exit
jest używany, gdy trzeba natychmiast przerwać program , bez możliwości przywrócenia lub wykonania odroczonej instrukcji czyszczenia, a także zwrócić kod błędu (który inne programy mogą wykorzystać do zgłoszenia tego, co się stało). Jest to przydatne w testach, gdy już wiesz, że po tym, jak jeden test się nie powiedzie, drugi również się nie powiedzie, więc równie dobrze możesz teraz po prostu zakończyć. Można tego również użyć, gdy program zrobił wszystko, co musiał, a teraz musi tylko zakończyć, tj. Po wydrukowaniu komunikatu pomocy.W większości przypadków nie będziesz używać
panic
(powinieneśerror
zamiast tego zwrócić ) i prawie nigdy nie potrzebujeszos.Exit
poza niektórymi przypadkami w testach i do szybkiego zakończenia programu.źródło
exit
w tym przypadku, po prostu spodziewałbym się dużego stosu nieudanych asercji.)Przede wszystkim
os.Exit()
można go użyć do normalnego wyjścia z programu bez błędu i bez paniki, więc jest to jedna kluczowa różnica. Innym jest to, że gdzieś panikę można złapać i zignorować lub zarejestrować za pomocąrecover
.Ale jeśli mówimy o błędnym kodzie wyjścia, powiedzmy:
Użyj,
panic
gdy coś pójdzie nie tak, prawdopodobnie błąd programisty, który powinien zostać wyłapany przed przejściem do produkcji. Dlatego drukuje stos.Użyj
os.Exit(errorCode)
lub czegoś takiego, jeśli chcesz:kontrolować kod zakończenia programu do celów skryptowych.
chcą uporządkowanego zakończenia w przypadku oczekiwanego błędu (np. błąd danych wejściowych użytkownika).
Zasadniczo panika jest dla ciebie, zły kod wyjścia jest dla twojego użytkownika.
źródło
Kluczowe różnice to:
os.Exit
pomija wykonanie odroczonej funkcji.os.Exit
można określić kod zakończenia.panic
kończy, podczas gdyos.Exit
nie jest. (Wydaje się, że inne odpowiedzi o tym nie wspominają.)Jeśli chcesz wykonać odroczoną funkcję, nie masz innego wyjścia
panic
. (Z drugiej strony, jeśli chcesz pominąć wykonywanie funkcji odroczonej, użyjos.Exit
.)Jeśli funkcja nie pusta jest zdefiniowana w następujący sposób:
return
lubpanic
Wtedy nie możesz zamienić na,
panic
wos.Exit
przeciwnym razie kompilator odmówi kompilacji programu, mówiąc „brak powrotu na końcu funkcji”. (Go jest tutaj bardzo głupi, nawetlog.Panic
nie kończy funkcji).W innych warunkach:
panic
gdy dzieje się coś naprawdę połączonego, np. Błąd logiki programowania.os.Exit
gdy chcesz natychmiastowego wyjścia z określonym kodem zakończenia.źródło