Varför har inte Go Try-Catch?
Go stöder avsiktligt inte try-catch, utan endast syntaxen panic-recover. Detta har orsakat missnöje hos många utvecklare som är vana vid felhantering med try-catch. Så, varför implementerar man inte try-catch? Det beror på att try-catch har flera problem.
try-catch-finally
Try-catch-satsen är en konstruktion för att hantera fel och undantag som kan uppstå under programkörning (runtime). Dessutom anger finally-satsen kod som ovillkorligen måste utföras, oavsett om ett undantag inträffar eller inte.
Felhantering och ansvar
Under 80- och 90-talen var felhanteringen mycket enkel. Felmeddelandena var enbart ”Floppy disk full”, ”Ingen diskett i enheten”, ”Ingen skrivbehörighet till disketten” och utvecklare från den tiden brukade kasta (throw) felet till felhanteringspunkten för att hantera det centraliserat. I den situationen fungerade try-catch-konstruktionen effektivt.
Men med tiden har situationen förändrats. Affärslogiken har blivit mer komplex, databaser och transaktioner har uppstått, och många API:er har anropats via nätverk vilket tvingade utvecklare att tolka ett stort antal förfrågningsmeddelanden, och till och med med uppkomsten av samtidig programmering behövde fel hanteras i andra trådar än huvudtråden.
Fel har blivit så komplexa att de inte längre kan hanteras på ett ställe, och ingen kan ta ansvar för alla fel. Här uppstår ett allvarligt problem med try-catch.
Ansvarsöverlåtelse med try-catch
Try-catch är, enkelt uttryckt, ett sätt för den som orsakat felet att skjuta över ansvaret (efterarbetet) för felet på någon annan. Mottagaren kan vara en catch-sats, föräldrametoden, förälderns förälders förälder, eller någon annan. Med andra ord, i en värld där felhantering ökar och blir mer komplex är try-catchs metod just ”någon annan fixar det nog”. Se 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 inte är tydligt vem som hanterar printStackTrace och det är omöjligt att veta vilken kod som orsakade felet. Än värre blir det ju mer logik som läggs till inom try-satsen. Men paradoxalt nog har utvecklare blivit beroende av try-catch, som överlåter ansvaret, ju mer komplex utvecklingen blir, de har slutat fundera på felhantering, deras ansvarskänsla har bleknat och de har glömt bort kärnan i fel- och undantagshantering. Så, hur löste golang detta problem?
panic, recover
En av fördelarna med Go är att det har flera system som är utformade för att göra utvecklare till bra utvecklare och hindra dem från att gå fel. Panic-recover är ett exempel på detta.
Vid första anblicken verkar panic och recover inte skilja sig från try-catch, men skillnaden är att de inte överför ansvaret till andra när ett problem uppstår. När en panic inträffar i Go, bör den lösas där panic inträffade, snarare än att skicka värdet utåt. Detta ger utvecklaren ansvaret för felhanteringen och leder till en mer genomtänkt övervägning av var, vem och hur felet ska hanteras. Det ger användaren självständighet samtidigt som det ger utrymme för reflektion.
Dessutom är valet av ordet panic mycket lämpligt, till skillnad från try-recover ger panic-recover bara med själva orden utvecklaren pressen att endast använda det i tydliga felsituationer, inte undantagssituationer. Naturligtvis missbrukar utvecklare inte recover utan använder det bara där det behövs. Detta är till stor hjälp för att skriva kortfattad kod i Go.