Varför har Go inte Try-Catch?
Go stöder avsiktligt inte try-catch, utan endast panic-recover-syntax. Detta har lett till klagomål från många utvecklare som är vana vid felhantering med try-catch. Så varför inkluderar man inte try-catch? Anledningen är att try-catch har flera problem.
try-catch-finally
Try-catch-satsen är en konstruktion för att hantera fel och undantagssituationer som kan uppstå under programkörning (runtime). Dessutom används finally-satsen för kod som ovillkorligen ska exekveras, oavsett om ett undantag inträffar eller inte.
Felhantering och ansvar
På 80- och 90-talet var felhantering mycket enkel. Felmeddelandena var begränsade till "diskett full", "ingen diskett i enheten" eller "ingen skrivbehörighet för disketten". Utvecklare under denna tid hanterade fel genom att kasta dem till en gemensam felhanteringspunkt. I sådana situationer fungerade try-catch-satsen effektivt.
Men med tiden förändrades situationen. Affärslogiken blev mer komplex, databaser och transaktioner uppstod, och otaliga API-anrop via nätverk krävde tolkning av en mängd förfrågningsmeddelanden. Dessutom, med uppkomsten av samtidig programmering, behövdes fel hanteras i andra trådar än huvudtråden.
Fel blev för komplexa för att hanteras på ett enda ställe, och ingen enskild entitet kunde ta ansvar för alla fel. Det är här ett allvarligt problem med try-catch uppstår.
Ansvarsförflyttning med try-catch
Try-catch är, kort sagt, en metod där den enhet som orsakar felet överför ansvaret (efterarbetet) för felhändelsen till någon annan. Denna mottagare kan vara catch-satsen, dess föräldrametod, eller föräldern till föräldern till föräldern till föräldern... av någon. Med andra ord, i en värld där felhantering blir allt mer omfattande och komplex, är try-catchs valda metod att "någon annan får ta hand om det". Låt oss titta på koden nedan.
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}
Problemet med koden ovan är att det är oklart vem som hanterar printStackTrace, och det är omöjligt att veta vilken del av koden som orsakade felet. Dessutom blir problemet ännu värre ju mer logik som läggs till i try-blocket. Paradoxalt nog, ju mer komplex utvecklingen blev, desto mer beroende blev utvecklarna av try-catch-satser som överförde ansvar. De reflekterade inte över felhantering, deras känsla av ansvar minskade, och i slutändan glömde de bort kärnan i fel- och undantagshantering. Så hur löste Golang detta problem?
panic, recover
En av fördelarna med Go är dess system som syftar till att göra utvecklare bättre snarare än att leda dem in på dåliga vägar. Panic-recover är ett sådant exempel. Vid första anblicken kan panic och recover verka likartade try-catch, men de skiljer sig åt genom att de inte överför ansvaret utåt när ett problem uppstår. När en panik inträffar i Go, bör problemet lösas på den plats där paniken inträffade, snarare än att värdet överförs utåt. Detta ålägger utvecklaren ansvaret för felhantering och uppmuntrar till en djupare reflektion över var, vem och hur felet ska hanteras. Det garanterar autonomi för användaren samtidigt som det lämnar utrymme för eftertanke.
Valet av ordet "panic" är också utmärkt; till skillnad från try-recover, ger panic-recover, enbart genom ordet, utvecklaren en press att endast använda det i klara felsituationer och inte i undantagssituationer. Detta leder naturligtvis till att utvecklare inte missbrukar recover utan endast använder det där det är nödvändigt. Detta bidrar i hög grad till att skriva koncis kod i Go.