Ροή ελέγχου

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
}

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

  • Χωρίς τελικό μπλοκ - μια σκέτη continue (χωρίς ένα ακόλουθο { ... }) είναι σφάλμα ανάλυσης στην Perl 5.42. Ήταν παλιότερα έγκυρη δήλωση μέσα στην κατασκευή given / when του χαρακτηριστικού switch, όπου περνούσε στο επόμενο when. Αυτό το χαρακτηριστικό αφαιρέθηκε στην 5.42· η continue έχει πλέον νόημα μόνο ως τελικό μπλοκ βρόχου.

  • Η 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#

Πλήρως συμβατό με το upstream Perl 5.42.

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

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

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

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

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

  • break - συνοδευτική δεσμευμένη λέξη του αφαιρεθέντος χαρακτηριστικού switch· όπως και η σκέτη μορφή given / when της continue, δεν είναι πλέον διαθέσιμη στην 5.42