Як мені вирватися з циклу в Perl?


295

Я намагаюся використовувати breakоператор у forциклі, але оскільки я також використовую суворі підпункти у своєму коді Perl, я отримую помилку:

"Перерва" у баревові не дозволена, тоді як "суворі підписки" використовуються за адресою ./final.pl 154.

Чи існує вирішення цього питання (окрім відключення суворої підписки)?

Мій код відформатований таким чином:

for my $entry (@array){
    if ($string eq "text"){
         break;
    }
}

22
І якби у вас не було "суворого", ви отримаєте помилку під час запуску, коли він не зміг би знайти підрозділ під назвою "перерва".
Пол Томблін

Відповіді:


441

О, я знайшов це. Ви використовуєте останній замість перерви

for my $entry (@array){
    if ($string eq "text"){
         last;
    }
}

Хоча це лише семантична різниця і не означає багато іншого, крім текстової узгодженості з командою "next".
Бритва Буря

1
не кажучи вже про те, що "перерва" є експериментальним ключовим словом у> 5.010, правда? тож ви можете отримати незаконну зовнішню помилку блоку, а не те, що ви повинні її використовувати. Єдиний спосіб, який би спрацював - це, якщо ви використали цикл час у заданому блоці, а потім перервите, який теоретично би працював так, як ви хотіли, якщо ви хочете, якщо ІФ (і лише в тому випадку), коли даний блок мав лише цикл час у ньому, і припускаючи, що ви тільки годували даними якоїсь скалярної змінної ... але чому все це працює просто для того, щоб використовувати перерву, це (дуже) погана форма, не кажучи вже про (бла!), просто кажучи, її "можливо" просто не добре ідея & не те, що ви можете подумати, що це
osirisgothra

25
чомусь я повністю не можу запам'ятати це ключове слово "останнє". завжди в кінці гугл 'perl break loop' :(
Thupten

Також працює так само для whileциклів (). my @array = ("_", "apple", "orange"); my $thing; while ($thing = shift @array){ last if $thing =~ /[A-Za-z]/; } print($thing); # "apple"
HoldOffHunger

175

Додаткові дані (якщо у вас є додаткові запитання):

FOO: {
       for my $i ( @listone ){
          for my $j ( @listtwo ){
                 if ( cond( $i,$j ) ){

                    last FOO;  # --->
                                   # |
                 }                 # |
          }                        # |
       }                           # |
 } # <-------------------------------

2
Насправді вам не потрібні дужки після ФОО:
cjm

14
Якщо у вас є інший код відразу після циклу для мого $ i, який ви також хочете пропустити. Зовнішній {} - це голий блок, який сам по собі є певним циклом, який може бути останнім / повторним / наступним.
ysth

18

Тут просто lastпрацювали б:

for my $entry (@array){
    if ($string eq "text"){
         last;
    }
}

Якщо ви вклали петлі, тоді lastвийдете з внутрішньої петлі. У цьому випадку використовуйте мітки:

LBL_SCORE: {
    for my $entry1 (@array1) {
        for my $entry2 (@array2) {
            if ($entry1 eq $entry2) { # Or any condition
                last LBL_SCORE;
            }
        }
    }
 }

Дане lastтвердження змусить компілятор вийти з обох циклів. Те ж саме можна зробити в будь-якій кількості петель, а мітки можна зафіксувати в будь-якому місці.


6

На великій ітерації мені подобається використовувати переривання. Просто натисніть Ctrl+, Cщоб вийти:

my $exitflag = 0;
$SIG{INT} = sub { $exitflag=1 };

while(!$exitflag) {
    # Do your stuff
}

Дуже корисна пропозиція дійсно. +1
Кев

@PeterMortensen - це добре працює у Windows, єдине, що потрібно пам’ятати про Windows, можливо, це увімкнути автоматичне вимивання, якщо ви надрукуєте для STDOUT '$ | = 1; `
MortenB
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.