Làm thế nào để tôi thoát ra khỏi một vòng lặp trong Perl?


295

Tôi đang cố gắng sử dụng một breakcâu lệnh trong một forvòng lặp, nhưng vì tôi cũng đang sử dụng chương trình con nghiêm ngặt trong mã Perl của mình, tôi gặp lỗi khi nói:

Bareword "phá vỡ" không được phép trong khi "subs subs" được sử dụng tại ./final.pl dòng 154.

Có một cách giải quyết cho việc này (bên cạnh việc vô hiệu hóa chương trình con nghiêm ngặt) không?

Mã của tôi được định dạng như sau:

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

22
Và nếu bạn không có "phụ nghiêm ngặt", bạn sẽ gặp phải lỗi thời gian chạy thay vào đó khi nó không thể tìm thấy một phụ có tên là "phá vỡ".
Paul Tomblin

Câu trả lời:


441

Ồ, tôi đã tìm thấy nó. Bạn sử dụng cuối cùng thay vì nghỉ

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

Mặc dù đây chỉ là một sự khác biệt về ngữ nghĩa và không có ý nghĩa gì khác ngoài tính nhất quán văn bản với lệnh "tiếp theo".
Dao cạo bão

1
không đề cập đến việc 'break' là một từ khóa thử nghiệm trong> 5.010 phải không? do đó bạn có thể nhận được một lỗi bất hợp pháp bên ngoài, không phải là bạn nên sử dụng nó. Cách duy nhất có thể hoạt động là nếu bạn sử dụng một vòng lặp while bên trong một khối nhất định và sau đó phá vỡ, theo lý thuyết sẽ hoạt động theo cách bạn muốn IF (và chỉ khi) khối đã cho chỉ có vòng lặp while trong đó và giả sử bạn chỉ cho ăn một số biến vô hướng ... nhưng tại sao tất cả những công việc đó chỉ để sử dụng nghỉ, đó là (rất) hình thức xấu, không đề cập đến (blah!) chỉ nói, "có thể" của nó không tốt ý tưởng & không phải những gì bạn có thể nghĩ nó là
osirisgothra

25
vì một số lý do, tôi hoàn toàn không thể nhớ từ khóa này 'cuối cùng'. luôn luôn kết thúc việc googling 'perl break loop' :(
Thupten

Ngoài ra, hoạt động tương tự cho whilecác vòng lặp (). my @array = ("_", "apple", "orange"); my $thing; while ($thing = shift @array){ last if $thing =~ /[A-Za-z]/; } print($thing); # "apple"
Hold OfferHunger 17/07/18

175

Dữ liệu bổ sung (trong trường hợp bạn có thêm câu hỏi):

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

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

2
Bạn thực sự không cần niềng răng sau FOO:
cjm

14
Bạn làm nếu bạn có mã khác ngay sau vòng lặp $ i của tôi mà bạn cũng muốn bỏ qua. {} Bên ngoài là một khối trống, bản thân nó là một loại vòng lặp vui nhộn có thể là cuối cùng / làm lại / tiếp theo.
ysth

18

Đơn giản chỉ cần lastlàm việc ở đây:

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

Nếu bạn có các vòng lặp lồng nhau, thì lastsẽ thoát khỏi vòng lặp trong cùng. Sử dụng nhãn trong trường hợp này:

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

Đưa ra một lasttuyên bố sẽ làm cho trình biên dịch đi ra từ cả hai vòng lặp. Điều tương tự có thể được thực hiện trong bất kỳ số vòng lặp và nhãn có thể được cố định ở bất cứ đâu.


6

Trên một vòng lặp lớn, tôi thích sử dụng các ngắt. Chỉ cần nhấn Ctrl+ Cđể thoát:

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

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

Đề nghị rất hữu ích thực sự. +1
Keve

@PeterMortensen - điều này hoạt động tốt trong các cửa sổ, điều duy nhất cần lưu ý cho các cửa sổ có thể là bật autoflush nếu bạn in lên STDOUT '$ | = 1; `
MortenB
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.