"goto" yra daugelio programavimo kalbų teiginys, kilęs iš anglų kalbos žodžių go ir to. Tai žymuo (komanda), leidžiantis atlikti tiesioginį šuolį į kitą programos vietą (etiketę), t. y. pereiti į kitą kodo eilutę praleidžiant tarpinį kodą.
Kas yra ir kaip veikia
goto veikimo principas paprastas: programoje pažymima vieta (etiketė), o kituose kodo taškuose pateikiamas goto teiginys, nurodantis šuolį į tą etiketę. Dažnai sintaksė atrodo panašiai kaip šis C kalbos pavyzdys:
if (condition) goto label; /* ... */ label: /* čia atliksime veiksmus */ Įvairiose kalbose sintaksė gali skirtis, tačiau esmė ta pati — nekontroliuotas šuolis tarp kodo vietų. Kai kurios kalbos, ypač žemesnio lygio (pvz., surinkimo kalbos), turi tokią galimybę natūraliai; kitos — aukštesnio lygio — ją riboja arba visai neturi.
Kurias kalbas tai palaiko ir kur — ne
- Daugelyje tradicinių kalbų, pvz., C, C++ ar Pascal, goto yra galimas ir naudojamas.
- Kai kurios kalbos rezervuoja žodį, bet jo nenaudoja: pavyzdžiui, Java turi goto kaip rezervuotą žodį, bet jis negali būti naudojamas programoje. (Rezervuotas žodis — tai žodis, kuris yra programavimo kalbos dalis ir negali būti naudojamas, pavyzdžiui, kintamiesiems pavadinti.)
- Moderniose aukšto lygio kalbose, tokiose kaip Python ar dauguma funkcinio stiliaus kalbų, paprastai tiesioginio goto nėra (kartais naudojami konstrukcijų pakaitalai arba specialios bibliotekos ir modifikacijos).
Kritika ir teorinis pagrindas
Kompiuterių moksle plačiai aptariama struktūrizuotų programų teorema, kuri teigia, kad bet kokią programą galima išreikšti naudojant ribotus pagrindinius valdymo srauto mechanizmus — tokius kaip sekos, pasirinkimo (if/switch) ir kartojimo (for/while) konstrukcijos — ir nereikia naudoti goto teiginių. Remiantis šia teorija, goto nėra būtinas rašant aiškias ir patikimas programas.
Istoriškai goto sulaukė daug kritikos (pavyzdžiui, E. W. Dijkstra laiškas „Go To Statement Considered Harmful“), nes plačiai naudojamas jis sukelia sunkiai sekamą, „išmėtytą“ valdymo srautą — tai mažina kodo skaitomumą, testavimą ir priežiūrą.
Kada goto gali būti pateisinamas
Nors bendrais atvejais rekomenduojama vengti goto, yra keletas situacijų, kur jis praktiškas arba net patogus:
- Resursų atleidimas ir klaidų valdymas C kalboje: kai funkcijoje reikia atlikti daugybę operacijų su galimu grąžinamu klaidų kodu ir reikia centralizuoto „cleanup“ bloko, goto į etiketę su atleidimo logika gali būti aiškesnis už išsišakojusias if/else grandines.
- Išėjimas iš kelių susikoncentruotų ciklų: kai reikia greitai išeiti iš kelių įdėtų ciklų, goto kartais naudojamas vietoje sudėtingų valdiklių ar papildomų signalinių kintamųjų.
- Automatiškai sugeneruotas kodas ir valstybinės mašinos: kai kodą generuoja įrankiai, goto gali suteikti paprastą ir greitą sprendimą valdymo srautui atvaizduoti.
- Žemas lygis ir optimizavimas: kai reikalingas maksimalus efektyvumas ir aiškus atvaizdavimas į mašininius šuolius (assembly), goto analogai natūraliai egzistuoja.
Alternatyvos
- Funkcijos / metodai: mažesni, aiškiai apibrėžti blokai, kurie grąžina reikšmes arba būseną.
- Kontrolės konstruktai: for, while, switch, if, break, continue — dažniausiai pakankami uždaviniams, kuriems nereikia goto.
- Išimtys (exceptions): daugelyje kalbų jos naudojamos klaidų valdymui vietoje daugybinių grįžimų ir goto.
- Struktūrinis dizainas: aiški programos architektūra, moduliai ir atskirtos atsakomybės mažina poreikį atlikti laisvus šuolius.
Geros praktikos patarimai
- Venkite goto ten, kur galima aiškiai ir paprastai naudoti struktūrizuotus konstrukcijas.
- Jei naudojate goto, aiškiai pažymėkite etiketes ir pridėkite komentarus, paaiškinančius kodavimo priežastį.
- Apribokite goto panaudojimą iki kelių išimčių (klaidų atveju ar specializuotų optimizacijų), kad nepadidintumėte sudėtingumo.
- Siekiant ilgalaikio palaikymo, svarstykite apie refaktoringą į funkcijas ar aiškesnes kontrolės struktūras, kai tik tai įmanoma.
Apibendrinant: goto yra galingas ir paprastas įrankis, tačiau dėl potencialaus poveikio kodo skaitomumui ir priežiūrai jis dažniausiai yra nerekomenduojamas. Tačiau tam tikrose situacijose — klaidų valdymas, generuotas kodas, žemo lygio optimizacijos — jo naudojimas gali būti pateisinamas.