1. 字符串中的数组内插
和标量一样,数组的内容同样可以被内插到双引号引起的字符串中
内插时,会在数组的各个元素之间自动添加分隔用的空格
@rocks = qw{ flitstone slate rubble };
print "quartz @rocks limestone\n";
数组被内插后,首尾都不会增加额外的空格
print "There rocks are: @rocks.\n";
print "There's nothing in the parens (@empty) here.\n";
如何把电子邮件放在双引号内
$email = "fred@bedrock.edu"; # 错!这样会内插@bedrock这个数组
$email = "fred\@bedrock.edu"; # 对@进行转义操作
$email = 'fred@bedrock.edu'; # 直接用单引号来定义字符串
内插数组中的某个元素时,会被替换成该元素的值
@fred = qw(hello dolly);
$y = 2;
$x = "This is $fred[1]'s place"; # This is dolly's place
$x = "This is $fred[$y-1]'s place"; # This is dolly's place
注意索引表达式会被当成普通字符串表达式处理
如果要在某个标量变量后面接着写左方括号,需要首先将这个方括号隔开,它才不至于被识别为数组引用的一部分
@fred = qw(eating rocks is wrong);
$fred = "right"; # 我们想说this is right[3]
print "this is $fred[3]\n"; # 用到了$fred[3],打印"wrong"
print "this is ${fred}[3]\n"; # 打印"right" (用花括号避开歧义)
print "this is $fred"."[3]\n"; # 还是打印right (用分开的字符串)
print "this is $fred\[3]\n"; # 还是打印right (用反斜线避开歧义)
2. foreach控制结构
处理整个数组或列表内的数据,foreach循环能逐项遍历列表中的值,依次提取使用
foreach $rock (qw/ bedrock slate lava/){
print "One rock is $rock.\n"; # 依次打印所有2种石头的名称
}
每次循环迭代时,控制变量都会从列表中取得新值
控制变量不是列表元素的copy,它就是列表元素本身,假如在循环中修改了控制变量的值,也就同时修改了这个列表元素
@rock = qw/ bedrock slate lava /;
foreach $rock(@rocks){
$rock = "\t$rock"; # 在@rocks的每个元素前加上制表符
$rock .= "\n"; # 同时在末尾加上换行符
}
print "The rocks are:\n", @rocks; # 各自占一行,并使用缩排
当循环结束时,循环变量仍是循环执行前的值,如果循环变量在循环嵌未被赋值,则为undef
$rock = 'shale';
@rock = qw/ bedrock slate lava /;
foreach $rock (@rocks){
...
}
print "rock is still $rock\n"; # 打印 'rock is still shale'
代码块中的...
为占位符,又叫yada yada操作符
3. Perl最喜欢的默认变量 $_
假如在foreach循环开头省略控制变量,perl就会使用默认变量$_
foreach (1..10){
print "I can count to $_!\n";
}
$_ = "Yabba dabba doo\n";
print; # 默认打印$_
4. reverse操作符
reverse操作符会读取列表的值(一般来自数组),并按相反次序返回新的列表
@fred = 6..10;
@barney = reverse(@fred); # 返回 10,9,8,7,6
@wilma = reverse 6..10; # 同上,但无需额外的数组
@fred = reverse @fred; # 倒序后保存到原来的数组
perl总是在赋值前先计算等号右边的表达式
reverse只是返回倒序后的列表,不会修改给它的参数
reverse @fred; # 错误用法
@fred = reverse @fred; # 正确用法
5. sort操作符
读取列表的值,依次按字符的内部编码顺序对它们进行排序
对字符串而言,就是字符在计算机内部表示的代码点
大写字符排在小写字符前面,数字排在字母之前,而标点符号则散落各处
@rocks= qw/ bedrock slate rubble granite /;
@sorted = sort(@rocks); # 返回 bedrock, granite, rubble, slate
@back = reverse sort @rocks; # 逆序,返回 slate, rubble, granite, bedrock
@rocks = sort @rocks;
@numbers = sort 97..102; # 得到 100, 101, 102, 97, 98, 99
sort操作符将数字当成字符串来排序
按默认的排序规则,任何以1开头的字符串都会被排在以9开头的字符串之前,此外,排序操作符和reverse操作符一样,不会修改原始参数,只是返回新的列表
sort @rocks; # 错误
@rocks = sort @rocks; #正确
6. each操作符
对数组和哈希使用each操作符
每次对数组调用each,会返回数组种下一个元素对应的2个值
- 数组索引
- 数组元素
require v5.12;
@rocks = qw/ bedrock slate rubble granite /;
while( ($index, $value ) = each @rocks ){
print "$index:$value\n";
}
如果不使用each,就得自己根据索引从小到大依次遍历,然后借助索引取得元素值
@rocks = qw/ bedrock slate rubble granite /;
foreach $index (0..$#rocks){
print "$index: $rocks[$index]\n";
}
7. 标量上下文和列表上下文
同一表达式出现在不同的地方时会有不同的意义
操作值按照数字进行操作时就是数字结果,而按照字符串进行操作时返回的则是字符串结果,其中起到决定性因素的是操作符,而不是被操作的各种变量或直接量
@people = qw( fred barney betty );
@sorted = sort @people; # 列表上下文: barney, betty, fred
$number = 42 + @people; # 标量上下文: 42 + 3 = 45
@list = @people # 得到3
$n = @people;
任何表达式都可以产生列表或标量,根据上下文而定
8. 在标量上下文中使用产生列表的表达式
@backwards = reverse qw/ yabba dadda doo /; # 会得到 doo, dabba, doo
$backwards = reverse qw/ yabba dadda doo /; # 会得到 oodabbadabbay
$fred = something; # 标量上下文
@pebbles = something; # 列表上下文
($wilma, $betty) = something; # 列表上下文
($dino) = something; # 还是列表上下文
如果是给列表赋值(不管其中元素的个数),那就是列表上下文
如果是给数组赋值,那还是列表上下文
标量上下文的例子
$fred = something;
$fred[3] = something;
123 + something
something + 654
if (something) {...}
while (something) {...}
$fred[something] = something;
列表上下文的例子
@fred = something;
($fred, $barney) = something;
($fred) = something;
push @fred, something;
foreach $fred (something) {...}
sort something
reverse something
print something
9. 在列表上下文中使用产生标量的表达式
@fred = 6 * 7; # 得到仅有单个元素的列表(42)
@barney = "hello" . ' ' . "world";
@wilma = undef; # 得到的是单个元素的列表,元素值为未定义的(undef)
@betty = (); # 清空数组的正确方法
10. 强制指定标量上下文
有时在列表上下文的地方需要引入标量上下文,可以使用伪函数scalar,它不是真正的函数,只用于告诉Perl这里要切换到标量上下文
@rocks = qw ( talc quartz jade obsidian );
print "How many rocks do you have?\n";
print "I have ", @rocks, " rocks!\n"; # 错误! 这会输出各种石头的名称
print "I have ", scalar @rocks, " rocks!\n"; # 正确,打印出来的是石头种数
11. 列表上下文中的<STDIN>
在标量上下文中,<STDIN>返回的是输入数据的下一行内容
在列表上下文中,<STDIN>返回则是所有剩下行的内容,1行1个元素,直到文件结尾
@line = <STDIN>; # 在列表上下文中读取标准输入
当输入数据来自某个文件时,它会读取文件的剩余部分。
但如果输入数据的来源是键盘, 键入Ctrl + D(Ctrl + Z)来告知系统,不会再有任何输入了
如果运行程序的人在键入三行数据,通过对应按键告知系统输入完毕(到达文件末尾),最后得到的数组就会包含三个元素,每个元素都是一个以换行符结尾的字符串,因为这些换行符也是输入的内容
@line = <STDIN>; # 一次读取所有行的内容
chomp(@lines); # 然后再去掉换行符
chomp(@lines = <STDIN>); # 一次读入所有行,换行符除外