【问题标题】:perl return values from sub get mixed up来自 sub 的 perl 返回值混淆了
【发布时间】:2013-07-11 02:44:14
【问题描述】:

我正在尝试从 perl 中的 sub 获取 2 个不同的哈希值。哈希在 sub 的输出中混合在一起。这是我的简化代码:

#!/usr/bin/perl

use strict;
use warnings;

sub sub1 {
    my (%h1, %h2);
    $h1{'1a'}++;
    $h1{'1b'}++;
    $h2{'2a'}++;
    $h2{'2b'}++;
    while ( (my $key, my $value) = each %h1 ){
        print "key: $key, value: $value\n";
    }
    print "\n";
    return (%h1, %h2);
}

my (%r1, %r2) = sub1();
while ( (my $key, my $value) = each %r1 ){
    print "key: $key, value: $value\n";
}

输出:

key: 1b, value: 1
key: 1a, value: 1

key: 1b, value: 1
key: 2a, value: 1
key: 2b, value: 1
key: 1a, value: 1

为什么会这样?我该如何纠正?谢谢。

【问题讨论】:

    标签: perl hashtable


    【解决方案1】:

    您可能应该阅读references

    Perl 子程序可以接受参数列表,也可以返回一个列表。例如,如果我这样做:

    array_sub ( @a, @b );
    
    sub array_sub {
        return print join ( ": ", @_ ) . "\n";
    }
    

    您会注意到,传递的两个数组将合并为一个参数列表,而无法分辨一个列表的开始位置和另一个列表的结束位置。

    哈希也会发生类似的事情:

    array_sub ( %a, %b );
    
    sub array_sub {
        return print join ( ": ", @_ ) . "\n";
    }
    

    这会将两个哈希(及其键)合并到一个列表中,然后传递给子例程。

    要绕过这个限制,您可以使用 references,它们基​​本上是指向实际数组或哈希所在的内存位置的标量值:

    array_sub { \@a, \@b );
    
    sub array_sub {
        my $ref_a = shift;
        my $ref_b = shift;
        my @sub_a = @{ $ref_a };
        my @sub_b = @{ $ref_b };
    

    在上面,我在数组前面放了一个反斜杠来获取数组的引用。为了取消引用它们(即将它们转回数组),我将 @{...} 放在引用周围。

    你必须在你的代码中做类似的事情:

    my ($r1, $r2) = sub1();   #Returns references;
    my @r1 = @{ $r1 };   #dereference
    my @r2 = @{ $r2 };   #dereference
    

    在你的子程序中:

    sub sub1 {
        ...
        return \%h1, \%h2;
    

    【讨论】:

      【解决方案2】:

      Perl 正在将您的两个哈希合并为一个并将它们存储在您的 %r1 变量中,除非您从子例程返回 references,否则这将总是发生。

      sub sub1 {
          my (%h1, %h2);
          $h1{'1a'}++;
          $h1{'1b'}++;
          $h2{'2a'}++;
          $h2{'2b'}++;
          while ( (my $key, my $value) = each %h1 ){
              print "key: $key, value: $value\n";
          }
          print "\n";
          return (\%h1, \%h2); # \(backslash) creates a hashref
      }
      

      然后你需要将这些引用存储在标量变量中:

      my ($r1, $r2) = sub1(); # scalar variables with references to %h1 and %h2
      
      # use %{ } to put $r1 in hash context
      while ( (my $key, my $value) = each %{ $r1 } ){
          print "key: $key, value: $value\n";
      }
      
      # prints 
      # key: 1b, value: 1
      # key: 1a, value: 1
      
      # key: 1b, value: 1
      # key: 1a, value: 1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-29
        • 1970-01-01
        • 2011-12-20
        • 1970-01-01
        • 2017-01-11
        • 1970-01-01
        • 2015-10-27
        • 2011-12-29
        相关资源
        最近更新 更多