在此示例代码中,数组引用的范围是否重要

时间:2012-02-20 11:22:01

标签: perl

#!/usr/bin/perl

    A();
    B();

    sub A {
        my @array = qw(value_1 value_2);
        $array_ref = \@array;
    }

    sub B {
        foreach my $i ( @{$array_ref} ) {
            print "Array Value: $i \n";
        }
    }

由于数组是使用' my'关键字,数组引用会丢失吗? 任何人都可以向我简要介绍一下。

3 个答案:

答案 0 :(得分:7)

不,变量的范围到期,但不是内存地址。数据将保留。

这不是你可以尝试过的吗? =)我只是复制/粘贴你的代码并尝试了它,它运行良好。

为了正确封装,你真的应该返回数组ref:

B(A());
# Or
my $aref = A();
B($aref);

sub A {
        my @array = qw(value_1 value_2);
        return \@array;
}

sub B {
    my $array_ref = shift;
    foreach my $i ( @$array_ref ) {
        print "Array Value: $i \n";
    }
}

答案 1 :(得分:3)

我绝对建议使用

use strict;

在Perl脚本中(把它放在最开始)。在这种情况下,它会抱怨$ array_ref未声明全局。它可能是混淆的主要原因:您使用$ array_ref而不以任何方式声明它,因此它被视为全局变量。

数组内容本身是保留的,因为它被这个变量引用,因此引用计数保持大于0(perl在内部使用引用计数来跟踪何时删除变量)。

当然,建议使用TLP帖子(没有全局)中显示的方法。

答案 2 :(得分:0)

实际上,在这个例子中使用my是有充分理由的 实际上,您希望每次通过子例程重新创建变量,否则您将更改之前获得的值。

use strict;
use warnings;
use 5.10.1;

my @array;
sub A{
  push @array, scalar @array; # add the length of @array to the end
  return \@array;
}

my @list;

for( 'A'..'D' ){
  my $current = A();
  push @list, $current;
  say join ' ', @$current;
}

say '';

say join ' ', @$_ for @list;
0
0 1
0 1 2
0 1 2 3

0 1 2 3
0 1 2 3
0 1 2 3
0 1 2 3

请注意@array的每个副本是如何相同的。


这就是每次调用子程序时都需要新副本的原因。

use strict;
use warnings;
use 5.10.1;

sub A{
  state $iter = 0;
  my @array;
  push @array, 0..$iter++;
  return \@array;
}

my @list;

for( 'A'..'D' ){
  my $current = A();
  push @list, $current;
  say join ' ', @$current;
}

say '';

say join ' ', @$_ for @list;
0
0 1
0 1 2
0 1 2 3

0
0 1
0 1 2
0 1 2 3