我正在使用我自己的子程序尝试map()。当我使用Perl的内置函数尝试它时,它可以工作。但是当我用自己的子程序尝试map()时,它失败了。 我无法指出导致错误的原因。
以下是代码段。
#!/usr/bin/perl
use strict;
sub mysqr {
my ($input) = @_;
my $answer = $input * $input;
return $answer;
}
my @questions = (1,2,3,4,5);
my @answers;
@answers = map(mysqr, @questions); # doesn't work.
@answers = map {mysqr($_)} @questions; #works.
print "map = ";
print join(", ", @answers);
print "\n";
答案 0 :(得分:6)
Map始终将参数列表的元素分配给$_
,然后计算表达式。因此,map mysqr($_), 1,2,3,4,5
会在每个元素1,2,3,4,5上调用mysqr
,因为$_
依次设置为1,2,3,4,5中的每一个。
在调用内置函数时经常可以省略$_
的原因是,许多Perl内置函数(如果没有给出参数)默认情况下将在$_
上运行。例如,lc
函数执行此操作。您的mysqr
函数不会执行此操作,但如果您更改它以执行此操作,则第一个表单将起作用:
sub mysqr {
my $input;
if (@_) { ($input) = @_ }
else { $input = $_ } # No argument was given, so default to $_
my $answer = $input * $input;
return $answer;
}
map(mysqr, 1,2,3,4,5); # works now
答案 1 :(得分:2)
不同之处在于,在第二种情况下,您明确地传递了参数,而在第一种情况下,您没有传递任何内容。
@answers = map(mysqr, @questions); # same as mysqr(), no argument passed
@answers = map {mysqr($_)} @questions; # $_ is passed on to $input
您可能会想到,当没有给出参数时,许多Perl内置函数使用$_
。但是,这不是用户定义的子例程的默认行为。如果您需要该功能,则需要自己添加。虽然被警告说这通常不是一个好主意。
请注意,如果您使用use warnings
(您应该使用的话),则会出现描述性错误:
Use of uninitialized value $input in multiplication (*) at foo.pl line 8.
它告诉您没有数据传递给$input
。
不使用警告不是从代码中删除错误,它只是隐藏它们,就像隐藏"低油"汽车警示灯不会阻止发动机故障。