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

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

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

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

  • Как правильно вернуть TRUE ?
  • Кроме того, как правильно продолжать ?

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

25
задан Lazer 26 August 2010 в 15:40
поделиться

3 ответа

Эквиваленты return, continue, break

  • return эквивалентны return.
  • next эквивалентно continue.
  • last эквивалентно break.

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

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

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

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

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

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

return TRUE if $_ == $a;

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

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

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

return TRUE unless $_ != $a;

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

Используя 'следующий' и 'последний'

Вы также можете использовать следующий и последний:

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++ (C++ имеет встроенный true и false; C99 имеет true и false условно доступные, если вы #include ). Вы можете дать определения для Perl следующим образом:

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

Однако будьте осторожны. Некоторые вещи будут «истинными», даже если они не равны ИСТИННОМУ; другие вещи будут «ложными», даже если они не равны FALSE.


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

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

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

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

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

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

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

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

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

58
ответ дан 28 November 2019 в 18:10
поделиться

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

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.

7
ответ дан 28 November 2019 в 18:10
поделиться

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

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

sub search {
    my $key = shift;
    foreach (@_) {
        return 1 if $_ == $key;
    }
    return ();
}
4
ответ дан 28 November 2019 в 18:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: