我对perl编程非常陌生。
在阅读循环时,对于foreach循环,我有两个例子。
一个例子是,
foreach ('hickory','dickory','doc') {
print $_;
print "\n";
}
输出: -
hickory
dickory
doc
$ _变量包含每个项目。所以,它打印出来。
在另一个例子中,他们说没有在print语句中指定$ _变量。只有那里的空打印声明。它如何打印foreach参数。
foreach ('hickory','dickory','doc') {
print;
print "\n";
}
输出: -
hickory
dickory
doc
对于这也是相同的输出。它如何打印值。在那本书中,他们没有给出任何解释。我在互联网上搜索过。但是我找不到任何东西。
答案 0 :(得分:5)
关于print
正在回答foreach
的问题,这里有一点关于$_
。
来自General Variables in perlvar
即使您没有使用它,Perl也会假设
$_
:
以下函数使用
$_
作为默认参数:
- abs,alarm,chomp,chop,chr,chroot,cos,defined,eval,evalbytes,exp,fc,glob,hex,int,lc,lcfirst,length,log,lstat,mkdir,oct,ord,pos ,print,printf,quotemeta,readlink,readpipe,ref,require,reverse(仅在标量上下文中),rmdir,say,sin,split(第二个参数),sqrt,stat,study,uc,ucfirst,unlink,unpack
所有文件测试(
-f
,-d
)除了-t
,默认为STDIN。请参阅-X
在没有
m//
运算符的情况下使用模式匹配操作s///
,tr///
和y///
(又名=~
)。如果没有提供其他变量,则
foreach
循环中的默认迭代器变量。
grep()
和map()
函数中的隐式迭代器变量。隐含变量
given()
。在测试
<FH>
,readline
,readdir
或each
操作的结果时放置下一个值或输入记录的默认位置本身作为while
测试的唯一标准。在while
测试之外,这不会发生。
$_
默认为全局变量。
正如您所看到的,它几乎可以在任何地方使用,并且确实使用了很多。请注意,perlvar页面描述了更多类似的变量,其中许多很容易了解。
这是一个例子。考虑一下我们从文件中读取行,想要丢弃只有空格或以#
(注释)开头的行,而其他人想要将空格分成单词。
open my $fh, '<', $file or die "Can't open $file: $!";
while (<$fh>)
{
next if not /\S/;
next if /^\s*#/;
my @words = split;
# do something with @words ...
}
让我们看看$_
在上面的示例中有多少用途。这是一个等效的程序
while (my $line = <$fh>)
{
next if not $line =~ m/\S/; # if not matching any non-space character
next if $line =~ m/^\s*#/; # if matching # after only (possible) spaces
my @words = split ' ', $line; # split $line by ' ' (any white space)
# do something with @words ...
}
比较这两个
<$fh>
条件中的文件句柄阅读while
分配给$_
,然后在循环中可用。
正则表达式匹配运算符默认情况下适用于$_
。 m
本身可以删除。
split
默认情况下会拆分$_
。我们还使用另一个默认值,用于分割字符串的模式,即' '
(任意数量的空格)。
一旦我们$line = <$fh>
与$_
的交易关闭(它在循环中未定义),我们必须在任何地方使用$line
。所以 要么或做while (<$fh>)
并使用$_
。
为了进一步说明这一点,让我们在每一行找到最长的大写字
use List::Util 'max';
my $longest_cap = max map { length } grep { /^[A-Z]/ } @words;
grep获取@words
中的列表并将块应用于每个元素。每个元素都分配给$_
,因此可以作为$_
在块内的代码中使用。这是正则表达式默认使用的。满足条件的那些传递给map,它也会迭代将它们分配给$_
,这当然是length的默认值。最后,来自List::Util的max
选择了最大的$_
。
请注意,while (<$fh>)
永远不会被写入,也不需要临时变量。
以下是一些相关文档。 I/O Operators in perlop讨论$_
以及所有相关事项。正则表达式部分位于Regexp Quote-Like Operators in perlop和perlretut中。另请查看split。
定期使用默认值并读取其他人必须了解的代码。当您编写自己的代码时,您可以选择是否使用$_
,因为总是可以引入词法变量而不是它。
那么,何时使用$_
作为默认值(不需要写入)以及何时不使用?
正确使用默认值,尤其是$_
,可以使代码更清晰,更易读。通常意味着更好的代码。但是很有可能将这一点推得太远,最终会出现模糊,棘手和脆弱的代码。所以需要很好的味道。
另一种情况是代码的某些部分因默认值为$_
而受益,而在其他地方则必须明确使用$_
。我要说的是,如果在一段代码中看到{{1}}超过一次或两次,则意味着应该有一个正确命名的变量。
总的来说,如果有疑问,只需命名一切。
答案 1 :(得分:2)
如果您未在foreach
循环中声明任何变量,则默认设置为$_
foreach关键字实际上是for关键字的同义词,所以你 也可以使用。如果省略VAR,则为每个值设置$ _。
所以它解释了第一个循环。
第二个循环,正如您现在已经知道的那样$_
是根据您的数组中的每个元素设置的,因为您省略了$ var
。
您可以将foreach循环与显式变量一起使用,如下所示:
foreach my $item ( @list )
{
print "My item is: $item\n";
}
或者你可以像你一样省略print仍然可以像@Dada那样工作,因为:
如果省略FILEHANDLE,则打印到上次选中(参见select) 输出句柄。如果省略LIST,则将$ _打印到当前选中的 输出句柄。
答案 2 :(得分:0)
我将解释为什么你用不同的语法得到相同的结果:
如果从foreach的开头省略控制变量 循环,Perl使用它最喜欢的默认变量$ _。这(除了其不寻常的名称)之外(大部分)就像任何其他标量变量一样。例如:
foreach ('hickory','dickory','doc') {
print $_;
print "\n";
}
输出:
hickory
dickory
doc
虽然这不是Perl唯一的默认默认值,但它是Perl最常见的默认值。您将看到许多其他情况,当您不告诉它使用其他变量或值时,Perl将自动使用$ _,从而使程序员免于必须考虑并键入新变量名称的繁重工作。为了不让你陷入悬念,其中一个例子是 print,如果没有其他参数,将打印$ _:
foreach ('hickory','dickory','doc') {
print; # prints $_ by default
print "\n";
}
输出: -
hickory
dickory
doc