Occasionalmente, ma in modo ricorrente, affronto il seguente problema di ciclo:
CodeSnippet1
DO WHILE LoopCondition //LoopCondition depends on some pre-calculation from CodeSnippet1
CodeSnippet2 //CodeSnippet2 relies on LoopConditon=true
CodeSnippet1
LOOP
Il problema che vedo qui è la duplicazione del codice di CodeSnippet1.
A prima vista, sembra che dovrei spostare la condizione fino alla fine:
DO
CodeSnippet1
CodeSnippet2
LOOP WHILE LoopCondition
Questo non funzionerà poiché CodeSnippet2 presuppone LoopCondition = true. La prossima prova sarebbe:
DO
CodeSnippet1
IF LoopCondition THEN CodeSnippet2
LOOP WHILE LoopCondition
Di nuovo lontano dall'eleganza.
Nei linguaggi di programmazione C-like, si può fare quanto segue:
while(complicated-expression-containing-CodeSnippet1-and-LoopCondition) {
CodeSnippet2
}
Ma
a) questo può diventare difficile da capire e
b) non tutti i linguaggi di programmazione possono eseguire calcoli arbitrari, in particolare assunzioni variabili, durante la valutazione di alcune condizioni del ciclo.
Recentemente, ho trovato il seguente modo:
DO //endless loop
CodeSnippet1
IF NOT LoopCondition THEN EXIT LOOP
CodeSnippet2
LOOP
Questo tende a condurre una programmazione strutturata con loop ad absurdum / mi ricorda un po 'di stile di programmazione GoTo.
La mia domanda:
Ci sono (più o meno) ragioni oggettive per preferire uno degli stili di programmazione del ciclo menzionati sopra gli altri?
Modifica
So che in molte occasioni CodeSnippet1
insieme a LoopCondition
può essere incapsulato in una funzione restituendo la condizione del ciclo e abbiamo finito. Sono d'accordo. Ma questo non vale in generale. Sopra in b) Ho cercato di suggerire "assegnazioni di variabili". Qui in dettaglio:
Il mio esempio preferito, minimale ma reale: utilizzo di BufferedReader
in Java:
line = bufferedReader.readLine();
while(line != null) {
//CodeSnippet2
line = bufferedReader.readLine();
}
vs.
while((line = bufferedReader.readLine()) != null) {
//CodeSnippet2
}
Entrambe le varianti non sono soddisfacenti. Factoring out (line = bufferedReader.readLine()) != null
in una funzione che restituisce un valore booleano ha un nuovo problema: come recuperare line
? Usando una variabile globale / membro della classe solo per questo scopo?