

http://search.cpan.org/dist/Switch
在Perl的控制结构中,没有switch这种语句结构。你不得不使用长梯状的if、elsif和else语句进行多重检测,但你可以自己做一个。switch语句是这样工作的:让多个数值和一个测试值相比较,而执行与测试值相匹配的值,如果任意一个存在的话,执行对应代码。可以使用代码块去构建一个,因为块非常像只执行一次循环,实际上可以使用诸如last这样的循环控制语句离开这个块。
my $message;
print "Enter command: ";
while(<>) {
SWITCH: {
/^start$/ && do {
$message = "Starting\n";
last SWITCH;
};
/^stop$/ && do {
$message = "Stopped\n";
last SWITCH;
};
/^q$/ && do {
exit;
};
DEFAULT:$message = "No match.\n";
}
print $message;
print "Enter command: ";
}
这样一个switch语句就构造好了。在5.10版本时不用引入'use Switch',通过声明'use feature qw(switch)'可直接使用,语法也有所不同,如:'given-when'。该模块之后将会弃用,所以在5.10及以后的版本不应再使用。使用Switch模块的语法格式如下:
use Switch;
my $val=shift @ARGV;
switch ($val) {
case 'start' {print 'This start option';next}
case 'stop' {print 'This stop option';next}
else {print 'Please use start/stop to control this script!'}
}
There's always the switching in Perl 5.10, if you're running it of course.
use feature qw(switch);
given($a){
when(1) { print 'Number one'; }
when(2) { print 'Number two'; }
default { print 'Everything else' }
}
Please note that use Switch in any form is deprecated as it is being replaced (and removed in the next perl release) by perl's own form of switch statement, which is, as already answered:
given ($x){
when ('case1') { print 1; }
default {print 0; }
}
Using default case achieves the outcome you want. Also don't forget to use last if you want the switch to stop being evaluated after one condition is evaluated true.else is indeed what you are looking for:
switch ( $n ) {
case 1 { print "one\n" }
case 2 { print "two\n" }
else { print "other\n" }
}
The above would output "other" for $n=3 and "one" for $n=1.
相关的使用示例:
方法一:使用 LABEL
SWITCH: {
if (/^abc/) { $abc = 1; last SWITCH; }
if (/^def/) { $def = 1; last SWITCH; }
if (/^xyz/) { $xyz = 1; last SWITCH; }
$nothing = 1;
}
SWITCH: {
$abc = 1, last SWITCH if /^abc/;
$def = 1, last SWITCH if /^def/;
$xyz = 1, last SWITCH if /^xyz/;
$nothing = 1;
}
SWITCH: {
/^abc/ && do { $abc = 1; last SWITCH; }
/^def/ && do { $def = 1; last SWITCH; }
/^xyz/ && do { $xyz = 1; last SWITCH; }
$nothing = 1;
}
方法二:使用 feature module(5.10版本以上)
use feature "switch";
given($_) {
when (/^abc/) { $abc = 1; }
when (/^def/) { $def = 1; }
when (/^xyz/) { $xyz = 1; }
default { $nothing = 1; }
}
方法三:使用 Switch module
use Switch;
switch ($value) {
case 17 { print "number 17" }
case "snipe" { print "a snipe" }
case /[a-f]+/i { print "pattern matched"}
case [1..10,42] { print "in the list" }
case (@array) { print "in the array"}
case (%hash) { print "in the hash"}
else {print "no case applies"}
}
如果判断条件需要重复动作,则须加 next :
%traits = (pride => 2, sloth => 3, hope => 14);
switch (%traits) {
case "impatience" { print "Hurry up!\n"; next}
case ["laziness","sloth"] { print "Maybe tomorrow!\n"; next}
case ["hubris","pride"] { print "Mine's best!\n"; next}
case ["greed","cupidity","avarice"] { print "More more more!"; next}
}
或使用 fall-through 模式:
use Switch 'fallthrough';
%traits = (pride => 2, sloth => 3, hope => 14);
switch (%traits) {
case "impatience" { print "Hurry up!\n"}
case ["laziness","sloth"] { print "Maybe tomorrow!\n"}
case ["hubris","pride"] { print "Mine's best!\n"}
case ["greed","cupidity","avarice"] { print "More more more!" }
}
The Switch module deprecated in Perl 5.12
http://search.cpan.org/~jesse/perl-5.12.0/pod/perl5120delta.pod#Deprecated_Modules
Perl 5.10 introduced a real switch called given-when.The old Switch used source filtering and had other limitations.
http://search.cpan.org/perldoc?perl5100delta#Switch_and_Smart_Match_operator
The original Switch uses a source filter to do its work, and that's often a bad idea. Essentially, it pre-processes your literal source to create new code before perl compiles it. The module was never really intended to be heavily used, and it was more of a proof of concept to figure out what a real Perl feature could look like.
Perl 5.10 added the given-when construct to do what most people want from a switch-case, but it does quite a bit more. Learning Perl, 5th Edition devotes an entire chapter to it along with smart matching.
You can't make a Perl given-when with the if-elsif-else constructs. given-when lets you execute multiple blocks and well as add interstitial code. With if-elsif-else you execute exactly one branch.
The Switch module appeared in the core in 5.7.3 but was removed in 5.13.1
Prior to 5.10 there was a Switch module. This is deprecated at 5.10 and replaced by a given-when syntax. This FAQ describes it well:
http://perldoc.perl.org/perlfaq7.html#How-do-I-create-a-switch-or-case-statement
If you are using Perl 5.8 or earlier you must make do with if/elsif/else statements:
if($string =~ /^abc/) { $abc = 1; }
elsif($string =~ /^def/) { $def = 1; }
elsif($string =~ /^zyz/) { $xyz = 1; }
else{ $nothing = 1; }
or nested condition operators (?:):
$string =~ /^abc/ ? $abc = 1 :
$string =~ /^def/ ? $def = 1 :
$string =~ /^xyz/ ? $xyz =1 :
$nothing = 1;
There is a module in Core Perl (Switch) that gives you fake switch statements via source filters, but it is my understanding that it is fragile(脆弱的):
use Switch;
switch ($string) {
case /^abc/ {
case /^abc/ { $abc = 1 }
case /^def/ { $def = 1 }
case /^xyz/ { $xyz = 1 }
else { $nothing = 1 }
}
or the alternate syntax
use Switch 'Perl6';
given ($string) {
when /^abc/ { $abc = 1; }
when /^def/ { $def = 1; }
when /^xyz/ { $xyz = 1; }
default { $nothing = 1; }
}
或者使用变形的for循环语句:
for ($string) {
/abc/ and do {$abc = 1; last;};
/def/ and do {$def = 1; last;};
/xyz/ and do {$xyz = 1; last;};
$nothing = 1;
}
Just a short comment about the core Switch module that's been mentioned a couple of times in answers. The module in question relies on source filters. Among other things, that may result in wrong lines reported for errors. It's so bad that none of the core developers really remembers or cares to remember why it was accepted into the perl core in the first place.
Furthermore, Switch.pm will be the first Perl module ever to be removed from the perl core. The next major release of perl, 5.12.0, will still have it, albeit with a deprecation warning. That deprecation warning will go away if you explicitly install Switch.pm from CPAN. (You get what you ask for.) In the next release down the road, 5.14, Switch.pm will be entirely removed from core.
An equivalent solution that I like is a dispatch table.
my $switch = {
'case1' => sub { print "case1"; },
'case2' => sub { print "case2"; },
'default' => sub { print "unrecognized"; }
};
$switch->{$case} ? $switch->{$case}->() : $switch->{'default'}->();
注意:在Perl 5.8 中使用'Switch'时,可能会报错(即使没有错误发生),且这种问题难以查证。建议此版本下还是使用梯状的if..else这样的语句来代替,其官方也证实它在使用时会出现无可名状的问题,也就注定了它将在日后会从核心模块中移除了。