C中返回和继续关键字的Perl等价物是什么?

Laz*_*zer 25 perl

我使用此代码时收到此错误

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

code.pl第26行的语法错误,靠近")返回"

  • 什么是正确的方法return TRUE
  • 还有什么是正确的方法continue

我知道我应该在Perl方面考虑更多,而不是试图以这种方式将C代码转换为Perl.

Jon*_*ler 58

等价的回报,继续,突破

  • return 相当于回报.
  • next 相当于继续.
  • last 相当于休息.

'if'语句后跟块

你的问题是一个if语句后面总是跟着一个块括号.

if ($_ == $a) { return TRUE; }
elsif (...)   { ... }
else          { ... }
Run Code Online (Sandbox Code Playgroud)

对于所有它有时看起来有点冗长,我同意ysth这是Perl正确的事情.有趣的替代方案,请参阅Go编程语言,它将括号视为不必要并强制使用大括号.

'if'可以用作限定符

或者您可以使用ifas语句修饰符:

return TRUE if $_ == $a;
Run Code Online (Sandbox Code Playgroud)

请注意,在这种情况下,您不必在条件表达式周围使用括号,尽管添加它们没有任何害处.

使用'除非'

您也可以使用unless而不是if反转条件:

return TRUE unless $_ != $a;
Run Code Online (Sandbox Code Playgroud)

(并且,正如菲利普波特所指出的那样,混合unless一个否定的条件会使理解变得更难;这个例子直接与问题相同,但更好地写成一个if平等的.)

使用'next'和'last'

你可以使用nextlast类似:

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

注意foreach循环中的修正.(修正了问题以包括修正.)确保在脚本的顶部始终有' use strict;'和' use warnings;'.专家总是使用它们来确保它们没有犯错误.初学者应该出于完全相同的原因使用它们.

真假

此外,在其他的答案首先指出,Perl并没有预先定义的常量真假,任何超过C或C++ DO(C++有一个内置的truefalse; C99拥有truefalse有条件可用,如果你#include <stdbool.h>).您可以将Perl的定义提供为:

use constant TRUE => 1;
use constant FALSE => 0;
Run Code Online (Sandbox Code Playgroud)

但要小心.即使不等于TRUE,有些事情也会"真实"; 即使不等于FALSE,其他事情也将是"假的".


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

注释包含有关不使用$a$b作为变量的讨论.按顺序,相关评论是:

  • 请避免使用$ a,除非它在排序块中.- 扎伊德

  • @Zaid:好的一点是$ a和$ b在排序块的上下文中是特殊的.我不确定是否有法令表明它们永远不应该被使用 - 否则当潜伏着一个排序块时使用它们会很残忍,但是如果没有排序块,我看不出任何理由对待$ a和$ z不同. - 乔纳森莱弗勒

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

  • @phaylon:嗯,严格来说它们是'package globals'(参见Perl sort).是的,当你排序时,它们与词汇(我的)变量不同.如果您没有进行排序,那么如果您明确声明它们,则可以将它们视为词法. - 乔纳森莱弗勒

  • @Jonathan Leffler,他们也免于使用严格的qw(vars); 所以你可能没有注意到你正在从另一个范围内践踏它们.- Ven'Tatsu

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

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

  • ...但是不要使用带有负面条件的`除非',例如使用`!`或`!=`的条件.这是相当于双重否定的代码,它只是让人困惑. (4认同)
  • 请避免使用`$ a`,除非它在`sort`块中. (4认同)
  • @Zaid:好的一点是$ a和$ b在排序块的上下文中是特殊的.我不确定是否有法令表明它们永远不应该被使用 - 否则当潜伏着一个排序块时使用它们会很残忍,但是如果没有排序块,我看不出任何理由对待$ a和$ z不同. (2认同)

msc*_*cha 7

你的问题已经(非常!)全面地回答了Jonathan,但我想指出一些其他的,更加流行的方法来取代你的"搜索"功能.

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;
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅智能匹配文档,List :: MoreUtils, List :: Utilgrep.