首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

更佳编程之路 第三章 循环、整洁代码和 Perl 语言习惯用法 -1

更佳编程之路 第三章 循环、整洁代码和 Perl 语言习惯用法 -1

日常编程工作很少有什么魅力可言 ― 您必须使循环简单明了,语句分支正确并使代码非常整洁。幸运的是,有了Perl,我们可以轻松地用简化的循环构造、后缀 if/unless 分支语句和更多的方式编写优秀的代码。本文将带您尝试 Perl辅助您进行日常编码工作的几种特定方式。本文不打算教您 Perl,但是将提高您现有的 Perl 知识 ― 从初学者到中级水平。
Perl 循环Perl 具有标准的过程性循环构造:while() 循环、do-until() 循环和 for()循环。对于大多数程序员来说,这些构造几乎是第二天性(second nature)。另外,Perl还允许程序员轻松地针对某一列值或某一范围的测试条件进行迭代处理。
自 Perl 5.004 起,所有上述循环和 if/unless 构造都允许以 EXPRESSION 循环或 EXPRESSION if/unless 的形式使用反转表示法(语法上而不是语义上)。可以在 perldoc perlsyn 页面中找到 Perl 语法的详细描述。建议您在没有很好编写文档的情况下避免使用这种表示法。某些人,特别是具有 C/C++/Java 背景的人,看到某一行中只出现         print $_ foreach @array 时可能会感到困惑。      
while() 循环在执行之前检查它的条件。下例是一种寻求输入的常见方式:
清单 1. 最简单的 while() 循环
1
2
3
4
5
while (
)
{
# do something with the current input here
}




如果没有输入,则上面的代码将执行 0 次,如果有 N 次输入,则执行 N 次。除了在代码内部使用 next/last语句之外,没有其它方法来控制迭代次数。
do-until() 循环类似于 while()循环,但是它的内容将至少被执行一次。对于那些需要事先完成某件事的条件来说,它更合适,例如:
清单 2. 简单的 do-until 循环
1
2
3
4
5
6
7
8
my $i;
do
{
# put values in @list here...
...
$i = grep(/pattern/, @list);
}
until($i > 0);




在上例中,$i 在执行 grep 之前没有值,因此,我们可以使用一个 do-until循环并采用一种更自然的流程,而不是给它赋一个特殊的假值(fake value)然后再使用while。当然,不使用“until”而使用“while”也是可以的。
最后,与 do-until() 和 while() 循环采用一个参数不同的是,for() 循环采用三个参数。这就是 for() 循环最受世界各地的 C程序员青睐的原因所在 ― 可以很轻易地编写一个在一行中做所有事的 for() 循环。甚至有时程序员还编写没有循环体的 for()循环,因为所有工作都在循环参数自身内部完成。这种压缩的代码只有在代码模糊大赛(obfuscationcontest)中才受欢迎,在生产中却不受欢迎。
for()有一个初始化区(令人惊讶的是,初始化区常用于初始化变量)、一个迭代区(通常在这里递增循环计数器)和一个测试区(用于测试是否应该继续执行循环)。因此,等价的while() 和 for() 循环将是:
清单 3. 等价的 for() 和 while() 循环
1
2
3
4
5
6
7
8
9
10
for ($i=0; $i++; $i < 10)
{
# do something 10 times
}
$i=0;
while ($i < 10)
{
# do something 10 times
$i++;
}




For 与 foreach因为 for() 循环的文化传统(啊嗨)很丰富,所以建议您使用 foreach()。这是因为以下几个原因:         
  • foreach() 在英语中听起来更好。
  • foreach() 与 C 的传统截然不同,而 for() 可能会困惑程序员新手。
  • 在解释器级别上二者没有不同。
如果您觉得必须使用 for() 循环,建议您详细记录它出现的地方和使用它的原因。虽然 for()有其用处,特别是在三个参数的形式中更有用,但程序员新手和中级程序员最好避免使用这个工具。

在上例中,$i 从 0 递增到 9(有 10 个值)。for() 循环看起来当然整洁些,确实如此。然而,Perl 不愿意停留在 C现有的成就之上(因为一提起 for() 循环,人们最容易直接联想到 C 语言)。Perl 定义了一种 for()循环的改进语法,并为它起了个别名“foreach”。这意味着,无论在 Perl中的什么地方,只要可以使用“for”作为独立的语言构造,就可以使用“foreach”来替代“for”,反之亦然。
for 和 foreach:如何获得乐趣并获得成功上面提到的改进之处是:foreach() 循环以一个列表作为参数。这非常有用,因为列表是 Perl中的基本数据类型,可以用列表做很多奇妙的事。例如,在 Perl 中,将 2 到 40的列表写成“2..40”。对于列表中的每一个元素,foreach() 循环的主体都执行一次。与 while() 和 do-until()循环一样,“next”和“last”关键字可以更改程序的循环流程。“Next”和“last”分别跳至下一元素和全部退出循环。下面是一些示例:
清单 4. foreach() 循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
foreach (1..100)
{
# do something 100 times, $_ will be set to the current number
print "Now on iteration $_\n";
}
foreach (1..20,101..120)
{
# do something 40 times, $_ will be set to the current number
}
foreach my $counter (0..1)
{
# do something twice, $counter will be 0, then 1
}
foreach my $i (0..1000)
{
next unless $i%5;                      # next if this number is a multiple of 5
print "$i is not a multiple of 5...\n";
next unless $i%7;                      # next if this number is a multiple of 7
print "$i is not a multiple of 7...\n";
next unless $i%12;                     # next is this number is a multiple of 12
# $i is now not a multiple of 12, 5, or 7
print "$i is a lucky, lucky number to have met you...\n";
}
# here we use the Perl map operator to create a list of 100 even numbers
# see chapter 5 for details on the map and grep operators
foreach (map { $_ *= 2 } 0..99)
{
print "Even number: $_\n";

返回列表