【问题标题】:What are the Perl equivalents of return and continue keywords in C?C 中 return 和 continue 关键字的 Perl 等价物是什么?
【发布时间】:2010-08-27 06:23:24
【问题描述】:

我在使用此代码时遇到此错误

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。

【问题讨论】:

  • 您的搜索功能可以折叠成对any的调用:use List::MoreUtils 'any'; my $matched = any { $_ eq $a } @a_list;

标签: perl


【解决方案1】:

return、continue、break 的等价物

  • return 相当于 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;

(并且,正如Phillip Potter 指出的那样,将unless 与否定条件混合会使理解更加困难;该示例直接与问题相同,但最好写为具有相等性的if。)

使用“下一个”和“最后一个”

您可以类似地使用nextlast

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;”和“@987654345” @' 在脚本的顶部。专家总是使用它们来确保他们没有犯错。初学者应该出于完全相同的原因使用它们。

对与错

此外,正如在其他答案中首先指出的那样,Perl 没有预定义的常量 TRUE 和 FALSE,与 C 或 C++ 一样(C++ 有内置的 truefalse;C99 有 @ 987654348@ 和 false 有条件地可用,如果您 #include <stdbool.h>)。您可以为 Perl 提供以下定义:

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

不过要小心。即使不等于 TRUE,有些事情也会是“真实的”;即使不等于 FALSE,其他内容也会为“假”。


讨论'$a'和'$b'的使用

cmets 包含关于不使用$a$b 作为变量的讨论。依次,相关的 cmets 是:

  • 请避免使用 $a,除非它位于排序块中。 – Zaid

  • @Zaid:很好的一点是 $a 和 $b 在排序块的上下文中是特殊的。我不确定是否有法令要求它们永远不应该被使用——当还有一个排序块潜伏在周围时使用它们会很糟糕,但是在没有排序块的情况下,我看不出有任何理由对待 $a 和不同于 $z。 ——乔纳森·莱弗勒

  • $a 和 $b 是全局变量,因此其行为与词法不同。 – phaylon

  • @phaylon:好吧,严格来说,它们是“全局包”(参见 Perl sort)。是的,当您进行排序时,它们与词汇(我的)变量不同。当您不进行排序时,如果您明确声明它们,它们可以被视为词汇。 ——乔纳森·莱弗勒

  • @Jonathan Leffler,它们也免于使用 strict qw(vars);所以你可能不会注意到你正在从另一个范围内践踏它们。 – Ven'Tatsu

指出显而易见的问题:我只使用了$a,因为问题确实如此——我没有用大量细节淹没原始海报,而是主要关注要点。比如lastnext的讨论没有提到循环标签。

也就是说,“避免使用$a$b 作为变量”的建议是合理的;出于所指出的原因,它们是特殊名称,使用它们会留下可能会或可能无法检测到的错误的可能性。

【讨论】:

  • ...但永远不要将unless 用于否定条件,例如使用!!=。它相当于双重否定的代码,只会让人感到困惑。
  • 请避免使用$a,除非它在sort 块中。
  • @Zaid:很好的一点是 $a 和 $b 在排序块的上下文中是特殊的。我不确定是否有法令要求它们永远不应该被使用——当还有一个排序块潜伏在周围时使用它们会很糟糕,但是在没有排序块的情况下,我看不出有任何理由将 $a 与 $z 区别对待。
  • @Jonathan Leffler:$a 和 $b 是全局变量,因此其行为与词法不同。
  • @Jonathan Leffler,它们也不受 use strict qw(vars); 的约束,因此您可能不会注意到您正在从另一个范围内践踏它们。
【解决方案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;

有关详细信息,请参阅smart matchingList::MoreUtilsList::Utilgrep

【讨论】:

    【解决方案3】:

    Perl 没有内置的 true 和 false 常量。 true 的规范值为 1,false 的规范值为 ()(在列表上下文中为空列表,在标量上下文中为 undef)。

    编写代码的更惯用方式是:

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

    【讨论】:

      猜你喜欢
      • 2011-03-27
      • 2012-09-06
      • 1970-01-01
      • 2011-07-23
      • 1970-01-01
      • 2014-09-08
      • 2011-09-14
      • 2012-03-20
      • 2014-05-08
      相关资源
      最近更新 更多