Perl 程式設計/陣列變數
Perl 語法包括列表和陣列。
Perl 中的列表是有序的標量值集合。在程式碼中,它表示為用逗號分隔的值序列,這些值可能包含在標量變數中,也可能不包含在標量變數中。列表可用於一次進行多個賦值,並可作為多個內建函式和使用者定義函式的引數傳遞。
#!/usr/bin/perl
use strict;
use warnings;
my ($length, $width, $depth) = (10, 20, 15);
print "The values are: ", $length, $width, $depth;
| 注意 在構造列表時,不需要括號。它們僅用於優先順序。 |
在建立不包含空格的多個字串的列表時,Perl 提供了一種捷徑,可以避免鍵入多個引號和逗號。而不是
($name1, $name2, $name3, $name4) = ('Paul', 'Michael', 'Jessica', 'Megan');
你可以使用qw//運算子。此運算子使用任何非字母數字字元作為分隔符(通常為/字元),幷包含以空格分隔的裸字序列。分隔符將命令與其引數隔開。上面的行與以下內容相同
($name1, $name2, $name3, $name4) = qw/Paul Michael Jessica Megan/;
兩者都等於以下
($name1, $name2, $name3, $name4) = qw(Paul Michael Jessica Megan);
最後一個示例使用開放式和封閉式括號作為不同的分隔符。如果你選擇了開放式和封閉式版本的分隔符,你需要同時使用它們。否則,只需重複同一個符號兩次。例如,你不能鍵入qw<Paul Michael<你必須鍵入qw<Paul Michael>.
如果字串不包含 shell 元字元,你也可以濫用 glob 語法
($name1, $name2, $name3, $name4) = <Paul Michael Jessica Megan>;
| 注意 qw// 運算子產生的字串是單引號的,這意味著在集合中不會發生插值。如果需要在列表中包含變數,則不能使用此方法。 |
如上所示,列表可用於一次進行多個賦值。如果左側變數的數量與右側值的數量相同,則所有變數都按預期賦值給相應的值。
如果左側變數數量少於右側值的數量,則“額外”的值將被簡單地忽略
#!/usr/bin/perl
($length, $width) = (10, $w, 15); #$length gets 10, $width gets the value of $w. 15 is ignored
如果左側變數數量多於右側值的數量,則“額外”的變數將被賦值為預設值undef值
#!/usr/bin/perl
($length, $width, $depth) = (10, $w); #$length gets 10, $width gets the value of $w. $depth is undef
列表賦值的存在建立了在不使用中間臨時變數的情況下“交換”兩個變數的值的能力
#!/usr/bin/perl
$foo = 10;
$bar = 5;
($foo, $bar) = ($bar, $foo); #$foo now equals 5, while $bar equals 10;
Perl 中的陣列是一個包含列表的變數。陣列可以修改,新增和刪除元素,清空,或重新賦值為完全不同的列表。就像所有標量變數都以$字元開頭一樣,所有陣列變數都以@字元開頭。
| 注意 在 Perl 中,經常會錯誤地將“列表”和“陣列”這兩個術語互換使用。它們的意思並不相同。 一個很好的比喻是,列表(例如qw/foo bar baz/) 對於陣列(例如@values) 就像字串(例如'Paul') 對於標量變數(例如$name). |
陣列被賦值為值列表。值列表可以任意大小(甚至可以包含 0 個元素)。
#!/usr/bin/perl
@nums = (1,2,3,4,5);
@more = 6..1000; #using the 'range' operator
@none = (); # empty array.
@names = qw/Paul Michael Jessica Megan/;
@all = (@nums, @more); #@all contains all integers from 1 to 1000
最後一個示例說明了 Perl 的一個稱為“陣列扁平化”的功能。當陣列在列表中使用時,填充列表的是陣列的元素,而不是陣列本身。如上所述,列表只是一組標量值。因此,@all陣列包含 1000 個元素,而不是 2 個。
| 注意 雖然這暗示你不能建立“陣列的陣列”或“二維陣列”,但這些東西在 Perl 中確實存在。它們是透過使用引用來模擬的。 |
當陣列在標量環境下使用時 - 或者透過將標量變數賦值給陣列的值,或者在期望標量的操作或函式中使用它 - 陣列將返回其大小。也就是說,它返回當前包含的元素數量
#!/usr/bin/perl
@names = ('Paul','Michael','Jessica','Megan');
$how_many = @names;
print "I have a total of $how_many names\n";
| 注意 一個常見的誤解是,列表在標量環境下也會返回其大小。這是不正確的。事實上,在標量環境下不存在列表:在標量環境下使用逗號運算子不會建立列表,而是從左到右評估其每個引數,並返回最後一個引數 $name = ('Paul','Michael','Jessica','Megan');
print "The last name in my list is $name\n";
|
一般有兩種列印陣列值的方法。你可以直接列印陣列中的專案列表,或者你可以在雙引號字串中插值陣列。
@names = qw/Paul Michael Jessica Megan/;
print "My names are: ", @names, ".\n";
print "My names are: @names.\n";
在第一個示例中,print函式被賦予了 6 個引數:字串“My names are:”,@names中的四個值中的每一個,以及字串“.\n”。每個引數都是用$,變數(預設為空字串)的值分隔列印,導致陣列中的值被“擠壓”在一起
My names are: PaulMichaelJessicaMegan.
在第二個示例中,print函式被賦予了一個引數:一個包含插值陣列的字串。當 Perl 對陣列進行插值時,結果是一個字串,它由陣列中的所有值組成,用$"變數(預設為單個空格)的值分隔
My names are: Paul Michael Jessica Megan.
| 注意 這兩個$,和$"變數都可以更改為任何你喜歡的字串。例如,要以逗號和空格而不是僅僅以空格來分隔陣列的專案 $" = ', ';
print "My names are: @names.\n";
My names are: Paul, Michael, Jessica, Megan. 通常你不想這樣做,因為根據這些變數的預設值,這可能會在程式的其他部分造成問題!稍後將介紹一種更安全的方法來列印具有自定義分隔符的陣列。 |
使用方括號內的數字引用來訪問陣列的元素。因為陣列中的每個專案都是一個標量值,所以你需要使用$在引用值時。陣列的第一個元素是編號 0,其他所有元素從該編號開始向上計數。
負數將從陣列的右側向下計數。這意味著 -1 引用陣列的最後一個元素,-3 引用倒數第三個元素。讓我們看一些示例
@array = (1, 2, 3, 4, 5);
print $array[0]; # Prints 1
print $array[3]; # Prints 4
print $array[-1]; # Prints 5
如果你需要知道最後一個索引怎麼辦?$#array會為你返回它
@array = (1, 2, 3, 4, 5);
print $array[4]; # Prints 5
print $array[-1]; # Same as above
print $array[ $#array ]; # Also prints 5
一個常見的錯誤是這樣做
print @array[0]; # Also prints 1, but for the wrong reasons
事實上@array[0]是一個切片(即陣列的子陣列),它包含一個元素,而$array[0]是一個包含值 1 的標量。
你可能想知道,Perl 指令碼支援命令列引數。所有引數的列表都儲存在陣列@ARGV中,第一個條目包含第一個命令列引數。如果沒有傳遞命令列引數,則@ARGV是一個空陣列。
上面列出的陣列函式和運算子可以輕鬆地用於檢測傳遞的命令列引數,以及檢測提供的引數數量。