Альтернатива "последним" в циклах do - PullRequest
8 голосов
/ 06 декабря 2010

Согласно руководству по perl для for last (http://perldoc.perl.org/functions/last.html), last нельзя использовать для выхода из циклов do {}, но здесь не упоминается альтернатива. Скрипт I ' м ведение имеет такую ​​структуру:

do {
    ...
    if (...) 
    {
        ...
        last;
    }
} while (...);

и я почти уверен, что он хочет перейти к концу цикла, но он фактически выходит из текущей подпрограммы, поэтому мне нужно либо изменить last, либо изменить весь цикл, если есть лучший способ кто-то может порекомендовать.

Ответы [ 6 ]

16 голосов
/ 06 декабря 2010

Оберните do "loop" в пустой блок (который равен loop):

{
    do {
        ...
        if (...) 
        {
            ...
            last;
        }
    } while (...);
}

Это работает для последнего и повторного выполнения, но не для следующего; для этого места пустой блок внутри блока do:

do {{
    ...
    if (...) 
    {
        ...
        next;
    }
    ...
}} while (...);
10 голосов
/ 06 декабря 2010

do BLOCK while (EXPR) забавно тем, что на самом деле не является структурой цикла. Итак, last, next и redo не должны использоваться там. Избавьтесь от последнего и настройте EXPR, чтобы оценить ложь, когда такая ситуация найдена. Кроме того, включите строгий режим, который должен дать вам хотя бы предупреждение.

2 голосов
/ 04 января 2013

Почему бы просто не использовать цикл while?

while (...) {
  ...
  if (...) {
    last;
  }
}

Возможно, вам придется немного изменить свою логику, чтобы учесть тот факт, что ваш тест находится в начале, а не в конце цикла, но это должно быть тривиально.

Кстати, вы на самом деле МОЖЕТЕ выйти из цикла Паскаля, если используете Delphi, и Delphi DID подхватывает некоторое время, пока Microsoft не придет в себя и не выпустит языки .net.

2 голосов
/ 06 декабря 2010

Никогда не фанат циклов do / while в Perl. do на самом деле не цикл, поэтому last не выйдет из него. В нашем старом Pascal изумлении вы не могли выйти из петли в середине, потому что это было бы неправильно согласно мудрецу Никлаусу "Один вход / один выход" Вирта. Поэтому нам пришлось создать флаг выхода. В Perl это будет выглядеть примерно так:

my $endFlag = 0;
do {
    ...
    if (...) 
    {
        ...
        $endFlag = 1;
    }
} while ((...) and (not $endFlag));

Теперь вы можете видеть, что Паскаль так и не завоевал популярность.

1 голос
/ 06 декабря 2010

@ "http://perldoc.perl.org/functions/last.html": last не может использоваться для выхода из блока, который возвращает значение, например eval {}, sub {} или do {}, и не должен использоваться для выхода из операции grep () или map ().

Итак, используйте логическое значение в 'while ()' и установите его там, где у вас есть 'last' ...

0 голосов
/ 17 апреля 2018

Поздно на вечеринку - я недавно связался с for(;;).В моем элементарном тестировании для условных выражений A и B то, что вы хотите сделать с:

do {
    last if A;
} while(B);

, может быть выполнено как:

for(;; B || last) {
    last if A;
}

Немного уродливо,но, возможно, не более, чем другие обходные пути :).Пример:

my $i=1; 
for(;; $i<=3 || last) { 
    print "$i ";
    ++$i;
}

Выходы 1 2 3.И вы можете объединить приращение, если хотите:

my $i=1;
for(;; ++$i, $i<=3 || last) { 
    print "$i ";
}

(используя ||, поскольку оно имеет более высокий приоритет, чем ,)

...