Ροή ελέγχου

continue#

Συνδέει σε έναν βρόχο ένα μπλοκ που εκτελείται μετά από κάθε επανάληψη, ακριβώς πριν επαναελεγχθεί η συνθήκη.

Η continue δεν είναι ενσωματωμένη συνάρτηση - είναι δεσμευμένη λέξη ελέγχου ροής. Στη μία της εναπομένουσα σημασία εισάγει το τελικό μπλοκ ενός βρόχου while, until ή foreach. Το μπλοκ εκτελείται στο τέλος κάθε επανάληψης και οποτεδήποτε η next μεταφέρει τον έλεγχο εκτός του κύριου σώματος, αλλά όχι όταν το κάνουν οι last ή redo. Παίζει τον ρόλο που παίζει η τρίτη πρόταση ενός βρόχου for (init; cond; step) στη C.

Σύνοψη#

while (EXPR) { BODY } continue { STEP }
until (EXPR) { BODY } continue { STEP }
for VAR (LIST) { BODY } continue { STEP }
foreach VAR (LIST) { BODY } continue { STEP }
LABEL: while (EXPR) { BODY } continue { STEP }

Τι επιστρέφεται#

Η continue είναι δήλωση, όχι έκφραση. Δεν έχει τιμή επιστροφής και δεν μπορεί να εμφανιστεί σε θέση τιμής. Ο ίδιος ο βρόχος αποδίδει ό,τι απαιτεί το περιβάλλον του (τίποτα σε κενό περιβάλλον, την τελευταία αποτιμημένη έκφραση κάτω από κάποιες κατασκευές)· το μπλοκ continue δεν συμβάλλει σε αυτό.

Μοντέλο εκτέλεσης#

Για βρόχο με συνημμένο μπλοκ continue, κάθε επανάληψη εκτελείται με αυτή τη σειρά:

  1. Αποτίμηση της συνθήκης (ή λήψη του επόμενου στοιχείου της λίστας, για foreach). Αν ο βρόχος δεν πρέπει να ξανατρέξει, έξοδος.

  2. Εκτέλεση του κύριου σώματος.

  3. Εκτέλεση του μπλοκ continue.

  4. Επιστροφή στο βήμα 1.

Οι τρεις δεσμευμένες λέξεις ελέγχου βρόχου αλληλεπιδρούν με το μπλοκ continue διαφορετικά:

  • next - άλμα κατευθείαν στο βήμα 3. Το μπλοκ continue εκτελείται, και μετά επαναελέγχεται η συνθήκη. Αυτό είναι το νόημα του να υπάρχει μπλοκ continue: κατάσταση που πρέπει να προχωρά σε κάθε επανάληψη (μετρητής, αριθμός γραμμής, μια εφάπαξ επαναφορά αντιστοιχίας) εξακολουθεί να προχωρά όταν το σώμα βραχυκυκλώνει μέσω next.

  • last - εγκαταλείπει εντελώς τον βρόχο. Το μπλοκ continue δεν εκτελείται.

  • redo - επανεκκινεί το βήμα 2 χωρίς να επαναελέγξει τη συνθήκη και χωρίς να εκτελέσει το μπλοκ continue. Χρησιμοποιήστε την όταν το σώμα χρειάζεται άλλο ένα πέρασμα πάνω από τα δεδομένα της τρέχουσας επανάληψης (για παράδειγμα, μετά την παρεμβολή επιπλέον εισόδου).

Η παράλειψη του μπλοκ continue ισοδυναμεί με κενό.

Παραδείγματα#

Μετρητής που προχωρά ακόμη και όταν το σώμα παρακάμπτει:

my $n = 0;
for my $line (@lines) {
    next if $line =~ /^\s*#/;    # skip comments
    process($line);
} continue {
    $n++;                        # still counts skipped lines
}
print "scanned $n lines\n";

Ισοδυναμία με βρόχο for τύπου C - οι δύο μορφές παρακάτω είναι ίδιες, επειδή η Perl ξαναγράφει την κεφαλίδα τύπου C ως while με μπλοκ continue:

for (my $i = 1; $i < 10; $i++) { say $i }

my $i = 1;
while ($i < 10) {
    say $i;
} continue {
    $i++;
}

Επαναφορά εφάπαξ αντιστοιχιών και μετρητών γραμμής κατά τη ροή αρχείων με <>:

while (<>) {
    m?(fred)?   && s//WILMA/;
    m?(barney)? && s//BETTY/;
} continue {
    print "$ARGV $.: $_";
    close ARGV if eof;           # reset $.
    reset      if eof;           # reset ?pat?
}

Η αλληλεπίδραση με την redo - σημειώστε ότι η continue εκτελείται στη διαδρομή next αλλά όχι στη διαδρομή redo:

while (<>) {
    chomp;
    if (s/\\$//) {
        $_ .= <>;
        redo unless eof;         # merge continuation, re-enter body
    }                            # continue block skipped on redo
    process($_);
} continue {
    $seen++;                     # counts completed records only
}

Οριακές περιπτώσεις#

  • No trailing block - bare continue (without a following { ... }) is a parse error in Perl 5.44. It used to be a valid statement inside the switch feature’s given / when construct, where it fell through to the next when. That feature was removed in 5.44; continue now only has meaning as a trailing loop block.

  • Η last παρακάμπτει το μπλοκ continue. Αν το μπλοκ περιέχει εκκαθάριση που χρειάζεστε σε κάθε διαδρομή εξόδου, βάλτε την εκκαθάριση μετά τον βρόχο ή σε φύλακα εμβέλειας, όχι στο continue.

  • Η redo παρακάμπτει το μπλοκ continue. Αν το μπλοκ continue προωθεί έναν μετρητή, μια επανάληψη μέσω redo δεν θα τον αυξήσει - αυτό είναι συνήθως αυτό που θέλετε (η επανάληψη δεν έχει ακόμη ολοκληρωθεί) αλλά μπορεί να εκπλήξει κώδικα που στηρίζεται στο ότι ο μετρητής ταιριάζει με τον αριθμό εισόδων στο σώμα.

  • Το do { ... } while δεν είναι πραγματικός βρόχος - οι last, next και redo δεν λειτουργούν σε αυτό, και ένα τελικό μπλοκ continue είναι συντακτικό σφάλμα.

  • Βρόχοι με ετικέτα - το LABEL: προσαρτάται στη δεσμευμένη λέξη while / for / foreach, όχι στο continue. Οι next LABEL και last LABEL στοχεύουν τον βρόχο ως σύνολο· το μπλοκ continue αποτελεί μέρος αυτού του βρόχου.

  • Ένα μπλοκ από μόνο του είναι εφάπαξ βρόχος, οπότε ένα σκέτο { ... } continue { ... } αναλύεται και εκτελεί το μπλοκ continue μία φορά μετά το σώμα - σπάνια χρήσιμο, αλλά νόμιμο.

  • Foreach με ψευδωνυμοποίηση - μέσα σε βρόχο foreach η μεταβλητή του βρόχου είναι ψευδώνυμο του τρέχοντος στοιχείου της λίστας. Το μπλοκ continue εξακολουθεί να εκτελείται με αυτό το ψευδώνυμο εντός εμβέλειας, ώστε μπορείτε να επιθεωρήσετε ή να μεταβάλετε το στοιχείο εκεί όπως και στο σώμα.

Διαφορές από το upstream#

Fully compatible with upstream Perl 5.44.

Δείτε επίσης#

  • next - άλμα στο μπλοκ continue (αν υπάρχει) και επανέλεγχος της συνθήκης· η μόνη δεσμευμένη λέξη ελέγχου βρόχου που εκτελεί το μπλοκ continue

  • last - εγκατάλειψη του βρόχου εξ ολοκλήρου· παρακάμπτει το μπλοκ continue

  • redo - επανεκκίνηση του σώματος χωρίς επανέλεγχο της συνθήκης· παρακάμπτει το μπλοκ continue

  • return - εγκατάλειψη της περικλείουσας υπορουτίνας· επίσης παρακάμπτει το μπλοκ continue επειδή φεύγει από τον βρόχο

  • break - companion keyword of the removed switch feature; like the bare given / when form of continue, no longer available in 5.44