Waarom heeft Go geen Try-Catch?
Go ondersteunt opzettelijk geen try-catch en alleen de panic-recover syntaxis. Dit heeft geleid tot onvrede bij talloze ontwikkelaars die gewend zijn aan foutafhandeling met try-catch. Waarom is try-catch dan niet geïmplementeerd? Dit komt doordat try-catch verschillende problemen kent.
try-catch-finally
De try-catch-structuur is bedoeld voor het afhandelen van fouten en uitzonderingen die kunnen optreden tijdens de uitvoering van een programma (runtime). Bovendien bevat de finally-clausule code die altijd moet worden uitgevoerd, ongeacht of er een uitzondering is opgetreden.
Foutafhandeling en verantwoordelijkheid
In de jaren '80 en '90 was foutafhandeling zeer eenvoudig. Foutmeldingen waren beperkt tot 'Floppy disk vol', 'Geen floppy disk in drive' of 'Geen schrijfrechten voor floppy disk'. Ontwikkelaars in die tijd gooiden fouten naar een centraal punt voor afhandeling. In dergelijke situaties functioneerde de try-catch-structuur efficiënt.
Echter, met het verstrijken van de tijd veranderde de situatie. Bedrijfslogica werd complexer, databases en transacties kwamen op, talloze API's moesten via netwerken worden aangeroepen, en talloze verzoekberichten moesten worden geïnterpreteerd. Bovendien, met de opkomst van concurrency programming, moesten fouten worden afgehandeld in andere threads dan de hoofdthread.
Fouten werden te complex om op één plaats af te handelen, en het was niet langer mogelijk voor één entiteit om alle fouten te beheren. Hierdoor ontstond een ernstig probleem met try-catch.
Verschuiving van verantwoordelijkheid bij try-catch
Try-catch is, in één woord, een methode waarbij de entiteit die een fout veroorzaakt, de verantwoordelijkheid (de afhandeling) voor die fout doorschuift naar iemand anders. Dat kan de catch-clausule zijn, de bovenliggende methode, of de bovenliggende methode van de bovenliggende methode, enzovoort. Met andere woorden, in een wereld waarin foutafhandeling toeneemt en complexer wordt, is de door try-catch gekozen methode 'iemand anders zal het wel doen'. Bekijk de onderstaande code.
1try {
2 data = readFile("hello.txt"); // Lees het bestand "hello.txt"
3 structuredData = parseData(data); // Parseer de gelezen gegevens
4 insertDBStatus(structuredData[1]); // Voeg de status in de database in
5 startHTTPServer(structuredData[2]); // Start de HTTP-server
6} catch (Exception e) {
7 e.printStackTrace(); // Print de stack trace van de uitzondering
8}
Het probleem met de bovenstaande code is dat het onduidelijk is wie verantwoordelijk is voor het afhandelen van printStackTrace, en het is ook niet te achterhalen in welke code de fout is opgetreden. Hoe meer logica er in de try-instructie komt, hoe erger het probleem wordt. Het is echter paradoxaal dat naarmate ontwikkeling complexer werd, ontwikkelaars verslaafd raakten aan de try-catch-constructie die verantwoordelijkheid doorschoof. Ze dachten niet na over foutafhandeling, hun verantwoordelijkheidsgevoel nam af, en uiteindelijk vergaten ze de essentie van fout- en uitzonderingsafhandeling. Hoe heeft Golang dit probleem dan opgelost?
panic, recover
Een van de voordelen van Go is dat het verschillende systemen heeft om ontwikkelaars te begeleiden naar goede praktijken in plaats van hen op een verkeerd pad te brengen. Panic - recover is hiervan een voorbeeld. Panic en recover lijken op het eerste gezicht niet te verschillen van try-catch, maar ze onderscheiden zich doordat ze de verantwoordelijkheid niet extern plaatsen wanneer er een probleem optreedt. Wanneer er een panic optreedt in Go, moet de oplossing worden gevonden op de locatie van de panic, in plaats van de waarde extern te sturen. Dit legt de verantwoordelijkheid voor foutafhandeling bij de ontwikkelaar, waardoor deze dieper moet nadenken over waar, wie en hoe de fout moet worden afgehandeld. Het garandeert autonomie voor de gebruiker, terwijl er ruimte overblijft voor overweging.
Bovendien is de keuze van het woord 'panic' zeer uitstekend te noemen. In tegenstelling tot try-recover, legt panic-recover, alleen al door het woord, de druk op de ontwikkelaar om het alleen te gebruiken in duidelijke foutscenario's en niet in uitzonderingsscenario's. Van nature zal de ontwikkelaar recover niet misbruiken en het alleen gebruiken waar nodig. Dit draagt aanzienlijk bij aan het schrijven van beknopte code in Go.