Подтвердить что ты не робот

Каковы эквиваленты Perl для возврата и продолжить ключевые слова в C?

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

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 таким образом.

4b9b3361

Ответ 1

Эквиваленты возврата, continue, break

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

За операциями if следуют блоки

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

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

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

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

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

return TRUE if $_ == $a;

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

Использование 'except'

Вы также можете использовать 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;" в верхней части вашего script. Эксперты всегда используют их, чтобы убедиться, что они не допустили ошибок. Начинающие должны использовать их по той же причине.

ИСТИНА и ЛОЖЬ

Кроме того, как указано в других ответах, Perl не имеет предварительно определенных констант TRUE и FALSE, не более 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). Да, когда вы сортируете, они отличаются от лексических (моих) переменных. Когда вы не выполняете сортировку, тогда их можно рассматривать как лексические, если вы их явно заявляете. - Джонатан Леффлер

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

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

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

Ответ 2

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

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;

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

Ответ 3

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

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

sub search {
    my $key = shift;
    foreach (@_) {
        return 1 if $_ == $key;
    }
    return ();
}