La prima cosa è: non fare funzioni troppo complesse a cose complicate. Se non puoi evitare funzioni complesse ci sono diversi strumenti per gestire la situazione.
In C e in altre lingue, le persone utilizzano spesso goto
per il motivo.
void func() {
/* .. code .. */
if (condition()) goto end;
/* ... more code ...*/
end:
cleanup();
}
Ora ad alcune persone non piace goto
, anche in questi casi in modo che emulino goto
utilizzando un ciclo do { . } while(0)
:
void func() {
do {
/* .. code .. */
if (condition()) break;
/* ... more code ...*/
} while(0);
cleanup();
}
alcune lingue, per esempio PHP consente di dare un parametro al parametro break per saltare più livelli fuori:
function func() {
do {
/* .. code .. */
if(something() {
/* some code */
if (condition()) break 2;
/* ... */
}
/* ... more code ...*/
} while(0);
cleanup();
}
ma ci sono linguaggi con più costrutti di alto livello. C ++ per esempio ha dei distruttori, lì la gente usa il modello RAII
struct cleanup {
~cleanup() {
/* .. do cleanup ... */
}
}
void func() {
cleanup cleaner; // this stack object will be destroyed on exit, for that the destructor is being called
if (condition()) return;
/* ... more code ...*/
}
Alcuni altri linguaggi non hanno goto e non hanno un'interruzione annidata e nessun distruttore, quindi i programmatori Java devono convivere con nidificati se si utilizzano le eccezioni ... o rendono il codice più semplice.
public static void func() {
try {
/* .. code .. */
if(something() {
/* some code */
if (condition()) throw new ControlFlowException();
/* ... */
}
/* ... more code ...*/
} catch (ControlFlowException e) {
/* ignore */
} finally {
cleanup();
}
}
Quindi sì, i concetti esistono e differiscono per lingua.