【问题标题】:How can I pass and return hashes from a sub in Perl?如何从 Perl 中的 sub 传递和返回哈希?
【发布时间】:2012-06-21 17:13:01
【问题描述】:

我一直在玩 Perl 中的哈希。以下按预期工作:

use strict;
use warnings;

sub cat {
        my $statsRef = shift;
        my %stats = %$statsRef;

        print $stats{"dd"};
        $stats{"dd"} = "DDD\n";
        print $stats{"dd"};
        return ("dd",%stats);
}

my %test;
$test{"dd"} = "OMG OMG\n";

my ($testStr,%output) = cat (\%test);
print $test{"dd"};

print "RETURN IS ".$output{"dd"} . " ORIG IS ". $test{"dd"};

输出是:

OMG OMG
DDD
OMG OMG
RETURN IS DDD
 ORIG IS OMG OMG

当我将一个数组添加到组合中时,它会出错。

use strict;
use warnings;  sub cat {
        my $statsRef = shift;
        my %stats = %$statsRef;

        print $stats{"dd"};
        $stats{"dd"} = "DDD\n";
        print $stats{"dd"};         return ("dd",("AAA","AAA"),%stats); }
 my %test; $test{"dd"} = "OMG OMG\n";

my ($testStr,@testArr,%output) = cat (\%test);
print $test{"dd"};

print "RETURN IS ".$output{"dd"} . " ORIG IS ". $test{"dd"}. " TESTARR IS ". $testArr[0];

输出是:

OMG OMG
DDD
OMG OMG
Use of uninitialized value in concatenation (.) or string at omg.pl line 20.
RETURN IS  ORIG IS OMG OMG
 TESTARR IS AAA

为什么显示数组而哈希不显示?

【问题讨论】:

    标签: perl hash reference subroutine


    【解决方案1】:

    所有列表都在 Perl 中自动展平。因此,赋值运算符将无法神奇地区分子例程返回的列表之间的边界。在您的情况下,这意味着 @testArr 将使用 cat 给出的结果列表,而 %output 将一无所获 - 因此出现 Use of unitialized value... 警告。

    如果您需要专门返回哈希或数组,请使用引用:

    return ("dd", ["AAA", "AAA"], \%stats);
    

    ...后来,在作业中:

    my ($testStr, $testArrayRef, $testHashRef) = cat(...);
    my @testArray = @$testArrayRef;
    my %testHash  = %$testHashRef;
    

    【讨论】:

      【解决方案2】:

      除了raina77ow 的回答之外,我强烈建议只传递引用,而不是从类型转换为引用然后再返回。它更容易阅读并且编码的麻烦更少(恕我直言)

      use Data::Dumper;
      use strict;
      use warnings;
      sub cat {
          my $statsRef = shift;
          print $statsRef->{"dd"} ;
          $statsRef->{"dd"} = "DDD\n";
          print $statsRef->{"dd"} ;
          return ("dd",["AAA","AAA"],$statsRef); 
      }
      
      my $test = {} ;
      $test->{"dd"} = "OMG OMG\n";
      
      my ( $var, $arrRef, $hashRef ) = cat($test) ;
      
      print "var " . Dumper($var) . "\n" ;
      print "arrRef " . Dumper($arrRef) . "\n";
      print "hashRef " . Dumper($hashRef) . "\n";
      

      【讨论】:

      • +1 引用绝对有用,而且可能很干净,但有时它们确实会混淆——尤其是初学者。 )
      猜你喜欢
      • 2018-01-17
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 2014-07-02
      • 2023-03-28
      • 1970-01-01
      • 2011-04-20
      • 1970-01-01
      相关资源
      最近更新 更多