2012-02-20 33 views
3
#!/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'關鍵字聲明數組,數組引用可能會丟失嗎? 任何人都可以簡單介紹一下。是否在此示例代碼中的數組引用問題的範圍

回答

7

不,變量的作用域到期,但不是內存地址。數據將保留。

這難道不是你可以簡單嘗試的嗎? =)我只是複製/粘貼你的代碼,並嘗試它,它運行良好。

對於正確的封裝,但是,你真的應該返回數組引用來代替:

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"; 
    } 
} 
3

我絕對推薦使用

use strict; 
在Perl腳本

(把它放在最開始)。在這種情況下,它會抱怨$ array_ref是未聲明的全局。它可能是造成混淆的主要原因:您使用$ array_ref而不以任何方式聲明它,因此將其視爲全局變量。

數組內容本身被保留,因爲它被這個變量引用,因此引用計數保持大於0(perl在內部使用引用計數來跟蹤何時刪除變量)。

當然,像TLP文章(沒有全局變量)中顯示的方法是被推薦的。

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