Каковы Perl эквиваленты возврата и продолжения ключевых слов в C? - PullRequest
25 голосов
/ 26 августа 2010

Я получаю эту ошибку, когда использую этот код

sub search {
    my ($a, @a_list) = @_;
    foreach (@a_list) {
        if($_ == $a) return TRUE;
        # continue;
    }
    return FALSE;
}

синтаксическая ошибка в code.pl строка 26, рядом с ") return"

  • Каков правильный путь к return TRUE?
  • Кроме того, каков правильный путь к continue?

Я знаю, что я должен думать больше в терминах Perl, чем пытатьсяпреобразовать код C в Perl таким образом.

Ответы [ 3 ]

58 голосов
/ 26 августа 2010

Эквиваленты возврата, продолжения, разрыва

  • return - эквивалент возврата.
  • next - эквивалент продолжения.
  • last является эквивалентом break.

'if' после операторов следуют блоки

Ваша проблема в том, что за оператором if всегда следует блок внутри фигурных скобок.

if ($_ == $a) { return TRUE; }
elsif (...)   { ... }
else          { ... }

Для всех это иногда кажется немного многословным, я согласен с ysth , что это то, что Perl понял правильно.Интересный альтернативный вариант: см. Язык программирования Go , который рассматривает скобки как ненужные и обязывает использовать скобки.

'if' может использоваться в качестве квалификатора

Или вы можете использовать if в качестве модификатора оператора:

return TRUE if $_ == $a;

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

Использование 'кроме'

Вы также можете использовать unless вместо if для инвертирования условия:

return TRUE unless $_ != $a;

(И, как Филипп Поттер указал, что смешивание unless с отрицательным условием усложняет понимание; пример непосредственно делает то же самое, что и вопрос, но лучше написать как if с равенством.)

Используя 'next' и 'last'

Вы можете использовать next и last аналогично:

sub search {
    my ($a, @a_list) = @_;
    foreach (@a_list) {
        return TRUE if $_ == $a;
        last if $_ > $a;
        next if $ptom != LAST_QUARTER;
        ...
    }
    return FALSE;
}

Обратите внимание на исправление в цикле foreach. ( Вопрос дополнен исправлением. ) Убедитесь, что у вас всегда есть 'use strict; 'и' use warnings; 'вверху вашего скрипта.Эксперты всегда используют их, чтобы убедиться, что они не допустили ошибок.Начинающие должны использовать их по одной и той же причине.

TRUE и FALSE

Кроме того, как указано в других ответах, Perl не имеет предварительно определенных констант TRUE и FALSE, больше, чемC или C ++ do (C ++ имеет встроенные true и false; C99 имеет true и false, условно доступных, если вы #include <stdbool.h>).Вы можете предоставить определения для Perl как:

use constant TRUE => 1;
use constant FALSE => 0;

Будьте осторожны.Некоторые вещи будут «истинными», даже если они не равны TRUE;другие вещи будут 'ложными', даже если они не равны FALSE.


Обсуждение использования '$ a' и '$ b'

Комментарии содержат обсуждение отказа от использования$a и $b как переменные.Последовательно соответствующие комментарии были:

  • Пожалуйста, избегайте использования $ a, если оно не находится в блоке сортировки.- Zaid

  • @ Zaid: Хорошо, что $ a и $ b являются особенными в контексте блока сортировки.Я не уверен, есть ли указы, которые они никогда не должны использовать иначе - было бы ужасно использовать их, когда вокруг скрывается также блок сортировки, но в отсутствие блоков сортировки я не вижу никакой причиныобрабатывать $ a и отличаться от $ z.- Джонатан Леффлер

  • $ a и $ b являются глобальными и, следовательно, ведут себя иначе, чем лексические выражения.- phaylon

  • @ phaylon: ну, строго говоря, они являются «глобальными пакетами» (см. Perl sort ).Да, когда вы сортируете, они отличаются от лексических (моих) переменных.Если вы не выполняете сортировку, они могут рассматриваться как лексические, если вы объявите их явно.- Джонатан Леффлер

  • @ Джонатан Леффлер, они также освобождены от использования строгих qw (переменные);так что вы можете не заметить, что вы попираете их из другой сферы.- Ven'Tatsu

Указывая на очевидное: я использовал $a только потому, что вопрос - и вместо того, чтобы затопить оригинальный плакат с большим количеством деталейЯ придерживался в основном основных моментов.Например, при обсуждении last и next не упоминаются метки петель.

Тем не менее, совет "избегать использования $a и $b в качестве переменных" является обоснованным;они являются специальными именами по указанным причинам, и их использование оставляет возможность ошибок, которые могут быть или не быть обнаружимы.

7 голосов
/ 26 августа 2010

Джонатан получил (очень!) Исчерпывающий ответ на ваш вопрос, но я хотел бы указать на несколько других, более изощренных способов заменить функцию поиска.

use strict;
use warnings;
use 5.010;

my @a_list = (1, 2, 3);
my $a = 2;

# If you're using 5.10 or higher, you can use smart matching.
# Note that this is only equivalent if $a is a number.
# That is, "2.0" ~~ ["1", "2", "3"] is false.
say $a ~~ @a_list;

# Need to install List::MoreUtils, not a standard module
use List::MoreUtils qw(any);
say any { $a == $_ } @a_list;

# List::Util is a core module
use List::Util qw(first);
say defined first { $a == $_ } @a_list;

# No modules used, but less efficient
say grep { $a == $_ } @a_list > 0;

Для получения дополнительной информации,см. документацию для интеллектуального сопоставления , List :: MoreUtils , List :: Util и grep .

4 голосов
/ 26 августа 2010

Perl не имеет встроенных констант для true и false.Каноническим значением для true является 1, а для false - () (который является пустым списком в контексте списка и undef в скалярном контексте).

Более логичным способом написания вашего кода будет:

sub search {
    my $key = shift;
    foreach (@_) {
        return 1 if $_ == $key;
    }
    return ();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...