使用此代码时出现此错误
sub search {
my ($a, @a_list) = @_;
foreach (@a_list) {
if($_ == $a) return TRUE;
# continue;
}
return FALSE;
}
在code.pl第26行的语法错误,靠近“)返回”
return TRUE
的正确途径是什么?continue
的正确途径是什么?我知道我应该在Perl方面考虑更多,而不是试图以这种方式将C代码转换为Perl。
答案 0 :(得分:58)
return
相当于return。next
相当于continue。last
相当于break。你的问题是if
语句后面跟着一个大括号内的块。
if ($_ == $a) { return TRUE; }
elsif (...) { ... }
else { ... }
总而言之,它有时看起来有点冗长,我同意ysth这是Perl正确的事情。有关一个有趣的替代方案,请参阅Go编程语言,该语言将括号视为不必要的并强制使用大括号。
或者您可以使用if
作为语句修饰符:
return TRUE if $_ == $a;
请注意,在这种情况下,您不必在条件表达式周围使用括号,尽管添加它们没有任何害处。
您也可以使用unless
代替if
来反转条件:
return TRUE unless $_ != $a;
(并且,正如Phillip Potter指出的那样,将unless
与否定条件混合使得理解更难;示例直接与问题相同,但更好地写为{{1}与平等。)
您可以类似地使用if
和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;
”。专家总是使用它们来确保它们没有犯错误。初学者应该出于完全相同的原因使用它们。
另外,正如其他答案中首先指出的那样,Perl没有预定义的常量TRUE和FALSE,只不过是C或C ++(C ++有一个内置的use warnings;
和true
;如果false
),C99有条件可用true
和false
。您可以将Perl的定义提供为:
#include <stdbool.h>
但要小心。即使不等于TRUE,有些事情也会“真实”;即使不等于FALSE,其他事情也会“假”。
评论中包含有关不使用use constant TRUE => 1;
use constant FALSE => 0;
和$a
作为变量的讨论。按顺序,相关评论是:
请避免使用$ a,除非它在排序块中。 - Zaid
@Zaid:好的一点是$ a和$ b在排序块的上下文中是特殊的。我不确定是否有法令表明它们永远不应该被使用 - 否则当潜伏着一个排序块时使用它们会很残忍,但是如果没有排序块,我看不出任何理由对待$ a和$ z不同。 - Jonathan Leffler
$ a和$ b是全局变量,因此与lexicals不同。 - phaylon
@phaylon:嗯,严格来说它们是'package globals'(参见Perl sort)。是的,当你排序时,它们与词汇(我的)变量不同。如果您没有进行排序,那么如果您明确声明它们,则可以将它们视为词法。 - Jonathan Leffler
@Jonathan Leffler,他们也免于使用严格的qw(vars);所以你可能没有注意到你正在从另一个范围内践踏它们。 - Ven'Tatsu
指出显而易见的事实:我只使用了$b
,因为问题确实存在 - 而不是淹没原始海报的大量细节,我主要关注的是要点。例如,$a
和last
的讨论未提及循环标签。
那就是说,“避免使用next
和$a
作为变量”的建议是合理的;由于所指出的原因,它们是特殊名称,并且使用它们会留下可能或可能无法检测到的错误的可能性。
答案 1 :(得分: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;
有关详细信息,请参阅smart matching,List::MoreUtils的文档, List::Util和grep。
答案 2 :(得分:4)
Perl没有true和false的内置常量。 true的规范值为1
,false为()
(列表上下文中为空列表,标量上下文中为undef)。
编写代码的更具风格的方法是:
sub search {
my $key = shift;
foreach (@_) {
return 1 if $_ == $key;
}
return ();
}