Nei giorni del passato ...
In Pascal e Algol si poteva davvero solo fare il primo stile. Questo era noto come programmazione strutturata .
Una funzione in pascal e lo stile di programmazione era:
Function abs(arg:real;) : real;
Begin
real retval;
if retval > 0 then
reval = arg;
else
retval = arg * -1;
functionName := returnVal;
End;
La funzione ha restituito un parametro che gli è stato assegnato alla fine. Questa pseudo-variabile è stata influenzata probabilmente da Fortran che ha una notazione simile (ma può avere rendimenti multipli). La voce multipla di Fortran (si potrebbe usare la dichiarazione ENTRY
per avere una chiamata salta al centro di una funzione) e più punti di uscita era uno dei motivi per cui Vai alla dichiarazione Considerato Nocivo è stato scritto e la programmazione strutturata è nata come reazione da).
In Algol (un'altra influente lingua antica), il valore di ritorno di una procedura era l'ultima espressione valutata dalla procedura. Se volevi restituire qualcosa, dovevi portarlo fino alla fine e poi valutarlo.
Questo particolare stile / vincolo di programmazione è stato spesso utilizzato nel mondo accademico e ha influenzato una generazione di programmatori ed è stato il passaggio a linguaggi più eleganti dal codice stile "goto" prima con Fortran e assembly.
Nel mondo moderno ...
Il secondo stile, if
funge da dichiarazione di protezione è quasi sempre preferibile.
public static boolean returnMulti(Object arg) {
if (!validArg) {
return false;
}
more stuff;
return true;
}
Notare "ulteriori elementi" che indicano un'elaborazione che potrebbe essere ragionevolmente considerevole. Eliminando anticipatamente il caso non valido, si dovrebbe essere in grado di leggere more stuff
più facilmente.
D'altra parte, l'unico ritorno significa che quando stai camminando all'indietro attraverso il codice, c'è solo un punto che devi guardare.
funcA
stuff;
foo = funcB();
stuff;
Ok, quindi foo è il valore di ritorno di funcB()
...
funcB
stuff;
if(bar) return something;
stuff;
if(qux) return somethingElse;
stuff;
if(bletch) return anotherThing;
stuff;
if(blarg) return yetAnotherThing;
stuff;
return defaultThingy;
A questo punto, hai 5 punti diversi da cui puoi tornare. Non sai quale e quali condizioni hanno causato il valore di ritorno per funcB
, potrebbe essere stato qualsiasi di allora. Questo non vuol dire che il codice precedente sia un codice buono , ma non è raro da vedere.
Usando una variabile di ritorno si avrebbe codice che si potrebbe trovare l'istruzione return nella funzione e dire "era 5 a questo punto" e tornare indietro nel codice per vedere il flusso.
Inoltre, quando si ha una lingua con gestione esplicita delle risorse (malloc e libera piuttosto che garbage collection), si scoprirà che è più semplice effettuare una singola pulizia delle risorse allocate nella funzione alla fine piuttosto che chiamarle più volte e ne manca uno.
Per quanto riguarda la variabile temporanea ... si troverà in molte lingue che quando si scompone il codice per:
func foo()
retval = something;
return retval;
func bar()
return something;
I due compilano esattamente le stesse istruzioni (con una variabile temporanea - il compilatore deve mettere la memoria da qualche parte ).
Vedi anche