2015-02-08 40 views
2

只是想知道通過多次調用相同子例程來保留變量值的最佳方法。即在perl中通過多個子例程調用保留一個變量值

$someList = &someRoutine(100, 200); 
$someList2 = &someRoutine(100, 200); 

sub someRoutine { 
    $someAddition = 0; 
    foreach $someSum (@_){ 
     $someAddition += $someSum; 
    } 
    return $someAddition 
} 

print $someList; 
print $someList2; 

基本上,someList應打印300和someList2應打印600.我如何使它someList2打印600?我希望在多個子程序調用中保留$ someAddition。

回答

5

有幾種方法可以做到這一點。我將展示其中的兩個:

首先,在Perl的現代版本,你可以使用state

use feature qw/state/; 

print someRoutine(100,200), "\n"; 
print someRoutine(100,200), "\n"; 

sub someRoutine { 
    state $someAddition = 0; 
    foreach my $someSum (@_) { 
     $someAddition += $someSum; 
    } 
    return $someAddition; 
} 

在這個版本中,$someAddition變量將進行一次初始化爲零,並且只有一次。從那時起,這些價值將在通話之間保留。

另一個版本是使用詞法閉包。這裏有一個例子:

my $summer = makeSummer(); 
print $summer->(100,200), "\n"; 
print $summer->(100,200), "\n"; 

sub makeSummer { 
    my $someAddition = 0; 
    return sub { 
     $someAddition += $_ foreach @_; 
     return $someAddition; 
    } 
} 

第二個版本稍微複雜一些,但有兩個優點。首先,您可以簡單地通過調用makeSummer例程來製造一個新閉包來開始新的總結。其次,它可以在任何版本的Perl 5上運行,而不僅僅是最新版本的關鍵字state

如果你不與聲明的子之前初始化狀態變量而言,你也可以這樣做:

my $someAddition; 
sub someRoutine { 
    $someAddition = 0 unless defined $someAddition; 
    foreach my $someSum(@_) { 
     $someAddition += $someSum; 
    } 
    return $someAddition; 
} 

第四種方法是利用包全局變量。我最後一次保存這篇文章是因爲它最容易出現濫用和錯誤。但你在這裏;

our $someAddition = 0; 

someRoutine(100,200); 
print "$someAddition\n"; 

someRoutine(100,200); 
print "$someAddition\n"; 

sub someRoutine { 
    $someAddition += $_ foreach @_; 
} 

在這最後的版本,$someAddition是一個包全局,其全球範圍使它可內外生活在同一個命名空間內的任何子程序之外。

+0

謝謝你的回答。不幸的是,我們在學校使用的perl版本非常陳舊,所以狀態無法正常工作,而且我需要讓子程序返回一個包含數組中衆多項目的數組,因此我不知道詞法關閉是否是一個將工作。有沒有其他方法? – user2128074 2015-02-08 06:03:46

+0

'return($ someAddition,[@array]);'Perl的返回值不一定是同類實體。 – DavidO 2015-02-08 06:05:09

+0

對不起,如果我沒有正確解釋它,但$ someAddition是我返回的數組的一部分。 – user2128074 2015-02-08 06:07:28

4
  • 我假設您至少使用Perl 5的變種?從二十二年前的Perl 5的第一個版本開始,在子程序調用中使用與號爲&的做法是不好的做法。

  • 這也是至關重要的,你use strictuse warnings Perl程序的頂部,並聲明變量着y利用他們的第一點與my。這是一種可以發現許多簡單的編碼錯誤的措施,否則您可能會輕易忽略這些錯誤。

  • Perl變量名稱只能使用小寫字母,數字和下劃線。大寫字母保留爲全局標識符,如包名稱。

到目前爲止創建靜態變量的最簡單,最常用的方法就是聲明它的子程序之外。像這樣

use strict; 
use warnings; 

my $some_list = some_routine(100, 200); 
my $some_list2 = some_routine(100, 200); 

my $some_addition; 

sub some_routine { 
    $some_addition += $_ for @_; 
    return $some_addition 
} 

print $some_list, "\n"; 
print $some_list2, "\n"; 

輸出

300 
600 

如果你想保護的變量由比子程序以外的任何下面的代碼被訪問,然後只將它們括在括號,這樣

{ 
    my $some_addition; 

    sub some_routine { 
    $some_addition += $_ for @_; 
    return $some_addition 
    } 
} 
相關問題