Perl中foreach循環變量

看下面代碼:html

#!/usr/bin/perl -w
my $x = 1;
for $x (5 ... 8){
    print "In the for loop, \$x=[$x]\n";
}
print "\nOut of for loop, \$x=[$x]\n";
[/perl]

輸出結果以下:
[perl]
$ ./test.pl 
In the for loop, $x=[5]
In the for loop, $x=[6]
In the for loop, $x=[7]
In the for loop, $x=[8]

Out of for loop, $x=[1]


即 $x 作爲for循環的臨時變量,當for循環退出時,$x的值被恢復。
這是Perl中for的特性,必定要牢記。程序員

修改代碼以下:數組

use Scalar::Util qw(refaddr);
use strict;
my $x = 1;
print "Bef the for loop, \$x=[$x], addr=" . refaddr(\$x) . "\n\n";

for $x (5 ... 8){
    print "In the for loop, \$x=[$x], addr=" . refaddr(\$x) . "\n";
}
print "\nOut of for loop, \$x=[$x], addr=" . refaddr(\$x) . "\n";


輸出結果以下:oop

$ ./test.pl 
Bef the for loop, $x=[1], addr=6696768

In the for loop, $x=[5], addr=6537872
In the for loop, $x=[6], addr=6537872
In the for loop, $x=[7], addr=6537872
In the for loop, $x=[8], addr=6537872

Out of for loop, $x=[1], addr=6696768


顯然,在for循環中,變量$x被臨時指向了不一樣的內存地址,循環結束後,存儲$x的內存地址位置被還原。code


Perl語言中能夠用foreach處理整個數組或列表。foreach從列表的第一個元素一直循環執行到最後一個元素,一次迭代一個:htm

foreach $rock (qw{ bedrock slate lava}){
    print 「One rock is $rock.\n」;
}


控制變量(本例中爲$rock)每一次迭代從列表中取出一個新值。第一次爲「bedrock」,第三次爲「lava」。
 
須要注意的是控制變量不是這些列表元素中的一個拷貝,而是這些元素自己!也就是說,若是在循環中修改這個變量,那原始列表中的元素也會被修改(固然,對於列表的修改彷佛沒有什麼必要,可是對於數組就不同了),這條性質若是不清楚,可能對其結果感到吃驚。內存

@rocks=qw{ bedrock slate lava};
   foreach $rock (@rocks){
     $rock="\t$rock";       # @rocks的每個元素前都加入一個tab
     $rock.="\n";           # 每個元素後都加入換行符
   }
   print "The rocks are :\n",@rocks;


那麼當循環結束是$rock的值爲多少呢?其值通循環開始以前相同!foreach循環中控制變量的值會被Perl自動保存和恢復,當循環進行時,是沒有辦法改變其值得,循環結束時,變量的值會回到循環開始前,若是沒有值則爲undef。這意味着若是有一個變量和控制變量有相同的名字時,不用擔憂會混淆他們;也就是說,咱們能夠用已有的變量作循環變量,而不用擔憂它的值在循環中改變了。
 
$_ Perl中最多見的默認變量
 
若是在foreach循環中省略了控制變量,那Perl會使用其默認的變量:$_。除了其不尋常的名字外,這和普通的變量時同樣的,以下面的代碼所示:for循環

foreach(1..10){
   print 「I can count $_\n」;
}


固然$_不單單是能用在foreach中,雖然它不是Perl中惟一的默認變量,但無疑是使用最廣泛的。你會看到許多例子中Perl在沒有要求它使用某個變量或值得時候,會自動使用變量$_.這將節約程序員大量的時間來思考使用哪個變量。請看下面的例子:
$_ = "Yabba dabba doo\n";
print;  #打印出默認變量$_class

再次修改代碼以下:test

use Scalar::Util qw(refaddr);
use strict;
my $x = 1;
my @arr = (5, 6, 7, 8);
print "Bef the for loop, \$x=[$x], addr=" . refaddr(\$x) . "\n\n";
for $x (@arr){
    print "In the for loop, \$x=[$x], addr=" . refaddr(\$x) . "\n";
    $x .= "_perl";
}
print "\nOut of for loop, \$x=[$x], addr=" . refaddr(\$x) . "\n";
print "$_\n" foreach(@arr);


結果以下:

$ ./test.pl 

Bef the for loop, $x=[1], addr=6696768
In the for loop, $x=[5], addr=6537872
In the for loop, $x=[6], addr=6538256
In the for loop, $x=[7], addr=6696576
In the for loop, $x=[8], addr=6537568

Out of for loop, $x=[1], addr=6696768
5_perl
6_perl
7_perl
8_perl