如何在foreach声明中打印出这些值?

时间:2017-01-21 10:26:33

标签: perl foreach

我对perl编程非常陌生。

在阅读循环时,对于foreach循环,我有两个例子。

一个例子是,

foreach ('hickory','dickory','doc') {
   print $_;
   print "\n";
}

输出: -

hickory
dickory
doc

$ _变量包含每个项目。所以,它打印出来。

在另一个例子中,他们说没有在print语句中指定$ _变量。只有那里的空打印声明。它如何打印foreach参数。

foreach ('hickory','dickory','doc') {
   print;
   print "\n";
}

输出: -

hickory
dickory
doc

对于这也是相同的输出。它如何打印值。在那本书中,他们没有给出任何解释。我在互联网上搜索过。但是我找不到任何东西。

3 个答案:

答案 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>readlinereaddireach操作的结果时放置下一个值或输入记录的默认位置本身作为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::Utilmax选择了最大的$_

请注意,while (<$fh>)永远不会被写入,也不需要临时变量。

以下是一些相关文档。 I/O Operators in perlop讨论$_以及所有相关事项。正则表达式部分位于Regexp Quote-Like Operators in perlopperlretut中。另请查看split

定期使用默认值并读取其他人必须了解的代码。当您编写自己的代码时,您可以选择是否使用$_,因为总是可以引入词法变量而不是它。

那么,何时使用$_作为默认值(不需要写入)以及何时不使用?

正确使用默认值,尤其是$_,可以使代码更清晰,更易读。通常意味着更好的代码。但是很有可能将这一点推得太远,最终会出现模糊,棘手和脆弱的代码。所以需要很好的味道。

另一种情况是代码的某些部分因默认值为$_而受益,而在其他地方则必须明确使用$_。我要说的是,如果在一段代码中看到{{1}}超过一次或两次,则意味着应该有一个正确命名的变量。

总的来说,如果有疑问,只需命名一切。

答案 1 :(得分:2)

如果您未在foreach循环中声明任何变量,则默认设置为$_

来自perldoc about 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