傳統的 Perl 是沒有 switch 語法的,只能用 if/elsif/else、LABEL、或 switch 等模組來模擬,例如:
用 if/elsif/else 模擬:
for ($var_to_test) { if (/test1/) { } # 做 A elsif (/test2/) { } # 做 B elsif (/test3/) { } # 做 C else { } # 不然,做預設動作 }
使用 LABEL 模擬:
SWITCH: for (ref $var_to_test) { /^$/ die "不是 ref"; /SCALAR/ do { print_scalar($$ref); last SWITCH; }; /ARRAY/ do { print_array(@$ref); last SWITCH; }; /HASH/ do { print_hash(%$ref); last SWITCH; }; /CODE/ do { warn "無法顯示函式的 ref"; last SWITCH; }; # DEFAULT warn "使用者定義型態"; }
use Switch; switch ($val) { case 1 { print "number 1" } case "a" { print "string a" } case [1..10,42] { print "number in list" } case (\@array) { print "number in list" } case /\w+/ { print "pattern" } case qr/\w+/ { print "pattern" } case (\%hash) { print "entry in hash" } case (\&sub) { print "arg to subroutine" } else { print "previous case not true" } }
Perl 自 5.10 新增了 given/when 的語法來實踐 switch 語法,但功能更強大,做法如下:
use feature qw(say switch); given ($foo) { when (1) { say "\$foo == 1" } when ([2,3]) { say "\$foo == 2 || \$foo == 3" } when (/^a[bc]d$/) { say "\$foo eq 'abd' || \$foo eq 'acd'" } when ($_ > 100) { say "\$foo > 100" } default { say "None of the above" } }
不過,Perl 5.18 開始,把 given/when 標記為實驗性質,使用這個語法會出現警示訊息:
given is experimental at switch2.pl line 5.
到了 Perl 6,given/when 就變成正式的 switch 語法了 (無需使用 use 宣告),作法如下:
my $str = "bala foo"; given $str { say $_; when /foo/ { say "=> foo"; } when $_.chars > 10 { say "long str."; } default { say "Just say something else"; } }
Perl6 解決了長期以來 switch 語法懸缺的問題,由於 when 有強大的比對功能,比起其他程式語言的 switch 來說,更是具有超強的威力。 🙂