2017-02-15 50 views
12

今天,我偶然發現了Perl中的某些東西,我並不知道它:「本地化」了列表元素被分配到的變量。爲什麼Perl的foreach不需要用我的變量聲明呢?

這當然是在Perl文檔中記錄的 - 但是我沒有記住或閱讀它。

以下腳本演示了我的意思:

use warnings; 
use strict; 

my $g = 99; 

foreach $g (1..5) { 
    p($g); 
} 

sub p { 
    my $l = shift; 
    printf ("%2d %2d\n", $g, $l); 
} 

腳本打印

99 1 
99 2 
99 3 
99 4 
99 5 

因爲$g是 「本地化」 的foreach循環。

至於我可以告訴沒有區別,如果我在foreach循環中添加my$g

foreach my $g (1..5) { 

其實,我落得這樣做,因爲我覺得它使更清晰的變量是循環的本地。

我現在的問題是:是否有一種情況,我使用my確實有所作爲(因爲$g已被全球聲明)。

+2

如果您在全球範圍內聲明瞭該foreach,則不需要我的聲明。然而,它不會抱怨你再次宣佈它是奇怪的。例如,如果你刪除範圍,它會抱怨你已經聲明'$ g'我會去研究一下。 – 2017-02-15 08:27:23

+0

如果變量先前是用my聲明的,它將使用該變量而不是全局變量,但它仍然是本地化的。這種*隱式本地化只發生在foreach循環*中。 http://perldoc.perl.org/perlsyn.html#Foreach-Loops – user3606329

+0

@ user3606329這是正確的,但如果你拿這個代碼並刪除範圍它將會產生一個錯誤。該變量還不在循環內部,它是foreach語句的一部分。 – 2017-02-15 08:43:45

回答

8

所研究的行爲在Foreach Loops in perlsyn

在常規列表值foreach循環迭代記錄,並設置標量變量VAR是反過來的列表的每個元素。如果變量前面帶有關鍵字my,則它在詞彙範圍內,因此僅在循環內可見。

它繼續解釋

否則,該變量是隱式本地環路和在退出循環重拾昔日的價值。如果變量先前用my聲明,它將使用該變量而不是全局變量,但它仍然是本地化的循環。

因此,將其本地化爲my或將其保留至foreach應該沒有區別。

小好奇心是

這隱含定位在foreach環路發生時

所有這一切都在這個代碼段進一步澄清從Private Variables via my() from perlsub

foreach環默認爲在local的方式動態地確定範圍其索引變量。但是,如果索引變量的前綴爲關鍵字my,或者在範圍內已有一個按該名稱的詞彙,則會創建一個新的詞彙。

以來的新詞彙是在這兩種情況下內部創建不能有任何實際的差異

我絕對支持並建議在那裏放一個my

+0

據瞭解。但我在這裏看到的問題是'$ g'還不在循環中。所以如果'$ g'沒有被聲明並且之前被賦值,那麼'$ g'實際上是一個空值。 – 2017-02-15 08:47:04

+0

@Gerry在'foreach my $ i(1..4){}''$ i'的作用域被限制在循環中。它不存在「_before_」。如果前面已經聲明瞭$ i,那麼同樣沒有'my',只要它被看到就被本地化到循環的範圍。這是上面的報價告訴我們的。 – zdim

+0

好的,謝謝zdim。這就說得通了。 – 2017-02-15 09:13:52

相關問題