【问题标题】:perl print array from subroutineperl 从子程序打印数组
【发布时间】:2011-03-12 21:32:23
【问题描述】:
#! /usr/local/bin/perl 
sub getClusters
{
my @clusters = `/qbo/bin/getclusters|grep -v 'qboc33'`;
chomp(@clusters);
return \@clusters;
}

嗯,好吧..我如何在这个数组上打印,因为...

foreach $cluster (getClusters())
{ print $cluster."\n"; }

似乎不起作用。 谢谢。

【问题讨论】:

  • 您应该看到类似 ARRAY(0x80177c) 的内容(或其他十六进制值),对吧?如果是这样,Amadan 的回答是正确的。如果您遇到一些错误或不同类型的输出,您应该将其添加到您的问题中。
  • 您的代码中缺少use strict; use warnings;
  • 如果您提供有关问题的更多信息而不是“似乎不起作用”,您的问题会得到更好的回答。

标签: perl arrays foreach subroutine


【解决方案1】:

您正在返回一个引用,而不是在任何地方取消引用它。

foreach $cluster (@{getClusters()})

return @clusters;

两者都应该修复它(效果略有不同),首选第一个(你的数组有点大)。

您会为有限数量的元素使用非引用数组返回,通常是为了多返回(因此,通常限制为 2 或 3 个已知长度的数组)。

【讨论】:

  • -1,通过 arrayref 返回一个数组是不好的建议。删除该部分并 +1
  • @vol7ron:不是建议,我只是说什么可行。不过,你确实有道理。我明确说明了何时使用哪个。 (返回一个数组有它的位置,因此我更喜欢澄清而不是删除。)
  • +1。返回一个数组没有任何问题。有很多事情需要考虑,例如典型的数组大小,以及 sub 在上下文中的行为方式。
  • +1 返回以供您编辑。我还想更正我的评论:我的评论,正在返回一个列表,而不是一个数组。尽管如此,仍然存在性能损失,不需要发生,尽管它是最小的,但仍应鼓励使用 arrayrefs。
【解决方案2】:

如果您在use strict; use warnings; 下运行程序,它会告诉您失败的原因。正如 Amadan 所说,您需要取消引用返回的引用。

【讨论】:

    【解决方案3】:

    Perl 解决方案

    #!/usr/local/bin/perl
    use strict;
    use warnings;
    
    main();
    
    sub main{
       {
          local $"    =  "\n";
          print "@{getClusters()}";
       }
    }  
    
    sub getClusters{
       my @tArray  =  `/qbo/bin/getclusters|grep -v 'qboc33'`;
       chomp @tArray;
       return \@tArray;
    }
    

    通知

    1. 您不需要foreach 循环进行调试,您可以重置$" 运算符,但可以根据您的喜好分隔数组元素(例如, , ,或者我如何设置它上面的代码\n)。
    2. 返回数组 ref 是一个加分项,不要发回完整数组(干得好)
    3. 使用严格/警告,尤其是在调试时
    4. 尽量避免使用``的系统调用

    【讨论】:

    • 我仍然更喜欢这个解决方案,因为它引入了$",这是一种更不常见的特殊变量,在这种情况下减少了循环的需要。
    • 但是你修改了整个程序的$"local 意味着 getClusters 和它调用的任何东西都会看到修改后的值。像$" 这样被大量使用的东西,你正在乞求破坏一个更大的程序。如果您必须使用全局变量,请尽可能严格地限制效果。这更安全:my $clusters = getClusters(); { local $" = "\n"; print @$clusters; }
    • @daotoad: 你提出了一个很好的观点,我对此表示赞赏,但这就是使用 local 的原因 - 它仅将其应用于主函数和在其中调用的任何子例程. 注意: 您的 @$clusers 需要包含在一组双引号 ("") 中。此外,$" 并没有大量使用,主要用于调试。 更新:我已经修改了代码,如果getClusters() 是一个特殊情况,需要$" 为默认值,它可以在其中定义$"=' '。否则,限制到 main 的子块就可以了。
    • 我不知道为什么这个答案被否决了,它在解释和示例方面更胜一筹。
    【解决方案4】:

    为了方便,可以先接收返回值,然后像这样打印

    use strict;
    use warning;
    my $cluster_array = getClusters();
     my @cluster_return = @{$cluster_array};
    foreach my $cluster(@cluster_return){
     print"$cluster\n";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-22
      • 1970-01-01
      • 1970-01-01
      • 2016-02-21
      • 2019-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多