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是一个空数组。
上面列出的数组函数和操作符可以轻松地用于检测传递的命令行参数,以及检测提供的参数数量。