Apenas um comentário que esperançosamente ajudará na leitura de código Go no futuro: em muitos códigos de exemplo, panicé usado para sair em caso de erro, puramente devido ao fato de ser fácil de entender, e elimina a importação de quaisquer outros pacotes. Isso não significa que seja uma prática boa ou idiomática! . É apenas um dispositivo de economia de espaço, por exemplo, código. Reserva IRL panicpara situações muito especiais.
Intermernet
1
Hm .. bom) especialmente a abreviatura "IRL" - é nova para mim :) Você poderia explicar como o pânico elimina a importação de pacotes?
Timur Fayzrakhmanov
4
panicé um embutido. É recomendado (dependendo da circunstância) usar algo como os.Exit, log.Fataletc., que retornará um código de erro para o sistema operacional (sempre recomendado, se possível). Todos eles envolvem a importação de um pacote e, portanto, "bagunçam" o código de exemplo. O código de exemplo deve sempre ser usado apenas para demonstrar uma solução para um problema específico. Pode haver outros problemas com o código, que o tornam mais complexo se demonstrado de forma adequada e, portanto, prejudicam a explicação da resposta dada. YMMV.
Intermernet
1
Ok, entendi!) Muito obrigado) Vejo que há outra abreviatura para o meu vocabulário :)
Timur Fayzrakhmanov
2
NP, feliz em ajudar e aumentar seu léxico acrônimo :-)
Intermernet
Respostas:
84
Em primeiro lugar, sempre que você tiver uma pergunta "como ele é usado na prática", uma boa maneira de começar é pesquisar o código-fonte Go (ou qualquer base de código Go grande o suficiente, na verdade) e a documentação do pacote para respostas.
Agora, os.Exite panicsão bastante diferentes. panicé usado quando o programa, ou parte dele, atingiu um estado irrecuperável.
Quando panicé chamado, incluindo implicitamente para erros de tempo de execução, como indexação de uma fatia fora dos limites ou falha em uma asserção de tipo, ele para imediatamente a execução da função atual e começa a desenrolar a pilha da goroutine, executando quaisquer funções adiadas ao longo do caminho. Se esse desenrolar atingir o topo da pilha da goroutine, o programa será encerrado.
os.Exité usado quando você precisa abortar o programa imediatamente, sem possibilidade de recuperação ou execução de uma instrução de limpeza adiada, e também retornar um código de erro (que outros programas podem usar para relatar o que aconteceu). Isso é útil em testes, quando você já sabe que depois que um teste falhar, o outro também falhará, então você pode simplesmente sair agora. Isso também pode ser usado quando o programa tiver feito tudo o que era necessário e agora precisar apenas sair, ou seja, após imprimir uma mensagem de ajuda.
Na maioria das vezes, você não usará panic(em errorvez disso, deverá retornar um ) e quase nunca precisará os.Exitfora de alguns casos em testes e para o encerramento rápido do programa.
"Isso é útil em testes, quando você já sabe que depois que um teste falhar, o outro falhará também ..." Isso cheira a um antipadrão de teste de testes dependentes. Em um conjunto de testes bem escrito, cada teste é independente; o resultado de qualquer teste específico nunca deve determinar o resultado de qualquer outro teste.
gotgenes
1
@gotgenes Não necessariamente. Se eu tiver um teste de que uma determinada função retorna uma estrutura não nula e esse teste falhar, então posso esperar que todos os testes que examinam os valores da estrutura também falharão. É o código que depende, não os testes. (Dito isso, eu não usaria exitnesse caso, apenas esperaria uma grande pilha de afirmações com falha.)
David Moles
83
Em primeiro lugar, os.Exit()pode ser usado para sair do programa normalmente sem um erro, e não entre em pânico, então essa é uma distinção fundamental. Outra é que o pânico em algum lugar pode ser detectado e ignorado ou registrado usando recover.
Mas se estivermos falando sobre um código de saída incorreto, digamos:
Use panicquando algo der terrivelmente errado, provavelmente um erro do programador que deveria ter sido detectado antes de ir para a produção. É por isso que ele imprime a pilha.
Use os.Exit(errorCode)ou algo parecido se quiser:
controlar o código de saída do programa para fins de script.
deseja uma saída ordenada em um erro esperado (por exemplo, erro de entrada do usuário).
Basicamente, o pânico é para você, um código de saída ruim é para seu usuário.
"Basicamente, o pânico é para você, um código de saída ruim é para o seu usuário." <- Dica incrível
psousa
1
Poderíamos dizer que panic () está de alguma forma relacionado à chamada assert () usual no C simples? Bem ... eu sei que sempre removo a declaração de chamada antes de enviar para a produção, eu só os habilito ao testar um novo recurso. O que estou dizendo é que na maioria das vezes eu uso assert () para verificar invariantes que acho que devem ser verdadeiras em meu código. Você vê o mesmo uso para panic ()? :-)
yves Baumes
7
As principais diferenças são:
os.Exit ignora a execução da função adiada.
Com os.Exit, você pode especificar o código de saída.
panicestá encerrando, enquanto os.Exitnão. (Parece que outras respostas não mencionam isso.)
Se você precisa executar a função adiada, você não tem escolha a não ser panic. (Por outro lado, se quiser pular a execução da função adiada, use os.Exit.)
Se uma função não vazia for definida da seguinte maneira:
a função contém muitos ramos
todas as filiais são encerradas com returnoupanic
Então você não pode substituir panicpor, os.Exitcaso contrário, o compilador se recusará a compilar o programa, dizendo "falta retorno no final da função". (Go é muito burro aqui, mesmo log.Panicnão encerra uma função.)
Sob outras condições:
Use panicquando algo realmente conectado acontecer, por exemplo, erro de lógica de programação.
Use os.Exitquando quiser uma saída imediata, com o código de saída especificado.
panic
é usado para sair em caso de erro, puramente devido ao fato de ser fácil de entender, e elimina a importação de quaisquer outros pacotes. Isso não significa que seja uma prática boa ou idiomática! . É apenas um dispositivo de economia de espaço, por exemplo, código. Reserva IRLpanic
para situações muito especiais.panic
é um embutido. É recomendado (dependendo da circunstância) usar algo comoos.Exit
,log.Fatal
etc., que retornará um código de erro para o sistema operacional (sempre recomendado, se possível). Todos eles envolvem a importação de um pacote e, portanto, "bagunçam" o código de exemplo. O código de exemplo deve sempre ser usado apenas para demonstrar uma solução para um problema específico. Pode haver outros problemas com o código, que o tornam mais complexo se demonstrado de forma adequada e, portanto, prejudicam a explicação da resposta dada. YMMV.Respostas:
Em primeiro lugar, sempre que você tiver uma pergunta "como ele é usado na prática", uma boa maneira de começar é pesquisar o código-fonte Go (ou qualquer base de código Go grande o suficiente, na verdade) e a documentação do pacote para respostas.
Agora,
os.Exit
epanic
são bastante diferentes.panic
é usado quando o programa, ou parte dele, atingiu um estado irrecuperável.os.Exit
é usado quando você precisa abortar o programa imediatamente, sem possibilidade de recuperação ou execução de uma instrução de limpeza adiada, e também retornar um código de erro (que outros programas podem usar para relatar o que aconteceu). Isso é útil em testes, quando você já sabe que depois que um teste falhar, o outro também falhará, então você pode simplesmente sair agora. Isso também pode ser usado quando o programa tiver feito tudo o que era necessário e agora precisar apenas sair, ou seja, após imprimir uma mensagem de ajuda.Na maioria das vezes, você não usará
panic
(emerror
vez disso, deverá retornar um ) e quase nunca precisaráos.Exit
fora de alguns casos em testes e para o encerramento rápido do programa.fonte
exit
nesse caso, apenas esperaria uma grande pilha de afirmações com falha.)Em primeiro lugar,
os.Exit()
pode ser usado para sair do programa normalmente sem um erro, e não entre em pânico, então essa é uma distinção fundamental. Outra é que o pânico em algum lugar pode ser detectado e ignorado ou registrado usandorecover
.Mas se estivermos falando sobre um código de saída incorreto, digamos:
Use
panic
quando algo der terrivelmente errado, provavelmente um erro do programador que deveria ter sido detectado antes de ir para a produção. É por isso que ele imprime a pilha.Use
os.Exit(errorCode)
ou algo parecido se quiser:controlar o código de saída do programa para fins de script.
deseja uma saída ordenada em um erro esperado (por exemplo, erro de entrada do usuário).
Basicamente, o pânico é para você, um código de saída ruim é para seu usuário.
fonte
As principais diferenças são:
os.Exit
ignora a execução da função adiada.os.Exit
, você pode especificar o código de saída.panic
está encerrando, enquantoos.Exit
não. (Parece que outras respostas não mencionam isso.)Se você precisa executar a função adiada, você não tem escolha a não ser
panic
. (Por outro lado, se quiser pular a execução da função adiada, useos.Exit
.)Se uma função não vazia for definida da seguinte maneira:
return
oupanic
Então você não pode substituir
panic
por,os.Exit
caso contrário, o compilador se recusará a compilar o programa, dizendo "falta retorno no final da função". (Go é muito burro aqui, mesmolog.Panic
não encerra uma função.)Sob outras condições:
panic
quando algo realmente conectado acontecer, por exemplo, erro de lógica de programação.os.Exit
quando quiser uma saída imediata, com o código de saída especificado.fonte