GoSuda

Perché Go non ha Try-Catch?

By Rabbit Princess
views ...

Go, intenzionalmente, non supporta try-catch, ma solo la sintassi panic-recover. Ciò suscita le proteste di molti sviluppatori abituati alla gestione degli errori con try-catch. Ma qual è la ragione per cui non si include try-catch? Il motivo è che try-catch presenta diversi problemi.

try-catch-finally

L'istruzione try-catch è utilizzata per gestire situazioni di errore e di eccezione che possono verificarsi durante l'esecuzione di un programma (runtime). Inoltre, l'istruzione finally è utilizzata per inserire il codice che deve essere eseguito incondizionatamente, indipendentemente dal fatto che si sia verificata o meno un'eccezione.

Gestione degli errori e responsabilità

Negli anni '80 e '90, la gestione degli errori era molto semplice. I messaggi di errore si limitavano a 'Floppy disk pieno', 'Nessun floppy disk nell'unità', 'Nessun permesso di scrittura sul floppy disk' e, in quel periodo, gli sviluppatori, quando si verificava un errore, lanciavano (throw) l'errore fino al punto di gestione degli errori per una gestione comune. In questa situazione, l'istruzione try-catch funzionava in modo efficiente.

Tuttavia, col passare del tempo, la situazione è cambiata. La logica di business è diventata più complessa, sono comparsi i database e le transazioni, e, attraverso la rete, si è reso necessario interpretare numerosi messaggi di richiesta chiamando molteplici API, e persino, con l'avvento della programmazione concorrente, è diventato necessario gestire gli errori in thread diversi da quello principale.

Gli errori sono diventati così complessi da non poter essere più gestiti in un unico punto, e nessuno è più stato in grado di assumersi la responsabilità di tutti gli errori. È qui che si presenta un grave problema con try-catch.

Il trasferimento di responsabilità di try-catch

try-catch, in altre parole, è un metodo con cui colui che ha generato un errore delega la responsabilità (il compito successivo) dell'errore a qualcun altro. Questo destinatario può essere un'istruzione catch, il suo metodo genitore, il genitore del genitore del genitore del genitore... chiunque. In altre parole, in un mondo in cui la gestione degli errori è sempre più numerosa e complessa, il metodo scelto da try-catch è proprio 'Qualcuno lo farà'. Si osservi il codice seguente.

1try {
2    data = readFile("hello.txt");
3    structuredData = parseData(data);
4    insertDBStatus(structuredData[1]);
5    startHTTPServer(structuredData[2]);
6} catch (Exception e) {
7    e.printStackTrace();
8}

Il problema del codice sopra è che non è chiaro chi sia il responsabile della gestione di printStackTrace e non si riesce a capire da quale codice sia derivato l'errore. Inoltre, più logica viene inserita nell'istruzione try, peggiori diventano i problemi. Ma, paradossalmente, più lo sviluppo diventa complesso, più gli sviluppatori sono diventati dipendenti dall'istruzione try-catch, che trasferisce la responsabilità, non si preoccupano della gestione degli errori, la loro consapevolezza della responsabilità è diminuita e, alla fine, si sono dimenticati dell'essenza della gestione degli errori e delle eccezioni. Come ha risolto questo problema golang?

panic, recover

Uno dei vantaggi di Go è che ha diversi sistemi per fare in modo che gli sviluppatori non seguano una strada sbagliata, ma diventino buoni sviluppatori. panic-recover è un altro esempio.

A prima vista, panic e recover non sembrano diversi da try-catch, ma la differenza è che non trasferiscono la responsabilità all'esterno quando si verifica un problema. Quando si verifica un panic in Go, invece di restituire il valore all'esterno, è necessario risolvere il problema nel punto in cui si è verificato il panic. Ciò impone agli sviluppatori la responsabilità della gestione degli errori, inducendoli a riflettere in modo più approfondito su dove, chi e come gestire l'errore. Ciò garantisce l'autonomia degli utenti, lasciando al contempo spazio alla riflessione.

Inoltre, si può affermare che la scelta della parola panic sia molto appropriata, perché a differenza di try-recover, panic-recover impone agli sviluppatori, con la sola parola, di doverlo usare solo in chiare situazioni di errore, e non in situazioni di eccezione. Naturalmente, gli sviluppatori non abuseranno di recover e lo useranno solo dove è necessario. Ciò è di grande aiuto per scrivere codice conciso in Go.