在阅读循环时,对于foreach循环,我有两个例子.
一个例子是,
foreach ('hickory','dickory','doc') { print $_; print "\n"; }
输出: –
hickory dickory doc
$_变量包含每个项目.所以,它打印.
在另一个例子中,他们说没有在print语句中指定$_变量.只有那里的空打印声明.它如何打印foreach参数.
foreach ('hickory','doc') { print; print "\n"; }
输出: –
hickory dickory doc
解决方法
从General Variables in perlvar起
Here are the places where Perl will assume
$_
even if you don’t use it:
The following functions use
$_
as a default argument:
- 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 (in scalar context only),rmdir,say,sin,split (for its second argument),sqrt,stat,study,uc,ucfirst,unlink,unpack.
All file tests (
-f
,-d
) except for-t
,which defaults to STDIN. See 07001The pattern matching operations
m//
,s///
andtr///
(akay///
) when used without an=~
operator.The default iterator variable in a
foreach
loop if no other variable is supplied.The implicit iterator variable in the
grep()
andmap()
functions.The implicit variable of
given()
.The default place to put the next value or input record when a
<FH>
,readline
,readdir
oreach
operation’s result is tested by itself as the sole criterion of awhile
test. Outside awhile
test,this will not happen.
$_
is by default a global variable.
正如您所看到的,它几乎可以在任何地方使用,而且确实经常使用它.请注意,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本身可以被删除.
>默认情况下拆分$_.我们还使用另一个默认值,用于分割字符串的模式,即”(任何数量的任何空格).
>一旦我们做了$line =< $fh>与$_的交易是关闭的(它在循环中是未定义的)我们必须在任何地方使用$line.所以要么这样做要么做(< $fh>)并使用$_.
为了进一步说明这一点,让我们找到每行上最长的大写单词
use List::Util 'max'; my $longest_cap = max map { length } grep { /^[A-Z]/ } @words;
grep获取@words中的列表并将块应用于每个元素.每个项目都分配给$_,因此可以将块内的代码用作$_.这是正则表达式默认使用的.满足条件的那些传递到map,它也会迭代将它们分配给$_,当然是length的默认值.最后从List::Util开始最大值选择最大值.
请注意,$_永远不会被写入,也不需要临时变量.
以下是一些相关文档. I/O Operators in perlop讨论了while(< $fh>)和各种相关的事情.正则表达式部分是在Regexp Quote-Like Operators in perlop和perlretut.另外看看split.
定期使用默认值并读取其他人必须理解的代码.当你编写自己的代码时,你可以选择是否使用$_,因为总是可以引入一个词法变量而不是它.
那么,何时使用$_作为默认值(不需要写入)以及何时不使用?
正确使用默认值,特别是$_,可以使代码更清晰,更易读.通常意味着更好的代码.但是很有可能将这一点推得太远,最终会出现模糊,棘手和脆弱的代码.所以味道很好.
另一种情况是代码的某些部分受益于其默认值为$_而在其他地方则必须明确使用$_.我会说如果在一段代码中看到$_超过一次或两次,则意味着应该有一个正确命名的变量.
总的来说,如果有疑问,只需命名一切.