GoSuda

Hvorfor har Go ikke Try-Catch?

By Rabbit Princess
views ...

Go støtter bevisst ikke try-catch, men kun panic-recover syntaks. Dette har ført til misnøye blant et stort antall utviklere som er vant til feilhåndtering ved bruk av try-catch. Så, hvorfor har de ikke inkludert try-catch? Det er fordi try-catch har flere problemer.

try-catch-finally

Try-catch-setningen er en syntaks for å håndtere feil og unntak som kan oppstå under programkjøring (runtime). I tillegg inneholder finally-setningen kode som må utføres uavhengig av om et unntak oppstår eller ikke.

Feilhåndtering og ansvar

På 80- og 90-tallet var feilhåndtering svært enkel. Feilmeldingene var begrenset til "disk full", "ingen disk i stasjon" eller "ingen skrivetilgang til disk", og utviklere på den tiden håndterte slike feil ved å kaste dem opp til et felles feilhåndteringspunkt. I slike situasjoner fungerte try-catch-setningen effektivt.

Imidlertid har situasjonen endret seg over tid. Forretningslogikken har blitt mer kompleks, databaser og transaksjoner har oppstått, utallige API-kall via nettverk krever tolkning av et stort antall request-meldinger, og med fremveksten av samtidig programmering måtte feil til og med håndteres i andre tråder enn hovedtråden.

Feil har blitt for komplekse til å håndteres på ett sted, og ingen enkelt enhet kan lenger ta ansvar for alle feil. Her oppstår et alvorlig problem med try-catch.

Ansvarsfraskrivelse med try-catch

Try-catch er, kort sagt, en metode der den enheten som forårsaker feilen, skyver ansvaret (etterbehandlingen) for feilen over på noen andre. Denne "noen andre" kan være catch-blokken, dens foreldremetode, eller forelderen til forelderen til forelderen til forelderen... av en eller annen. Med andre ord, i en verden der feilhåndtering blir mer omfattende og kompleks, er try-catch sin tilnærming "noen andre vil ta seg av det". La oss se på koden nedenfor.

1try {
2    data = readFile("hello.txt");
3    structuredData = parseData(data);
4    insertDBStatus(structuredData[1]);
5    startHTTPServer(structuredData[2]);
6} catch (Exception e) {
7    // Skriver ut stack trace til feilen
8    e.printStackTrace();
9}

Problemet med koden ovenfor er at det er uklart hvem som håndterer printStackTrace, og det er umulig å vite hvilken kode som forårsaket feilen. Problemet blir enda mer alvorlig jo mer logikk som legges til i try-setningen. Paradoksalt nok, jo mer kompleks utviklingen ble, desto mer avhengige ble utviklerne av try-catch-setningen som fraskrev seg ansvar. De sluttet å tenke på feilhåndtering, ansvarsfølelsen ble svekket, og til slutt glemte de essensen av feil- og unntakshåndtering. Så, hvordan løste Golang dette problemet?

panic, recover

En av fordelene med Go er at det finnes flere systemer som veileder utviklere mot god praksis i stedet for å la dem falle inn i dårlige vaner. Panic-recover er et eksempel på dette. ​ Ved første øyekast kan panic og recover virke likt try-catch, men de skiller seg ut ved at de ikke overfører ansvaret utad når et problem oppstår. Når en panic skjer i Go, skal problemet løses på stedet der panikken oppsto, snarere enn å overføre verdien utad. Dette tildeler utvikleren ansvaret for feilhåndtering og oppmuntrer til en dypere refleksjon over hvor, hvem og hvordan feilen skal håndteres. Det gir brukeren autonomi, samtidig som det åpner for rom for ettertanke.

Valget av ordet "panic" er også svært utmerket. I motsetning til try-recover, legger panic-recover et press på utvikleren, bare ved ordlyden, om at det kun skal brukes i klare feilsituasjoner, ikke i unntakssituasjoner. Naturligvis vil utviklere ikke misbruke recover, men kun bruke det der det er nødvendig. Dette bidrar sterkt til å skrive konsis kode i Go.