Perl 6 中的 given-when

given-when 有两个小的改变, 并且这俩改变都是开启新行为的, 而不是限制已存在的行为。

第一个小的改变: when 的开关行为不仅仅是用于 given 块儿中的, 而是可以用在任何"主题化"的块儿中的, 例如 for 循环中或接收 $_作为参数的子例程中。

given $answer {
    when "Atlantis" { say "那是对的" }
    default { say "BZZZZZZZZZZZZZ!" }
}

for 1..100 {
    when * %% 15 { say "Fizzbuzz" }
    when * %% 3  { say "Fizz"     }
    when * %% 5  { say "Buzz"     }
    default      { say $_         }
}

sub expand($_) {
    when "R" { say "红警" }
    when "G" { say "绿警" }
    when "B" { say "蓝警" }
    default  { say $_     }
}

但是甚至不接受 $_作为参数的子例程也得到了它们自己的词法变量 $_供修改。所以规则就是"现在, 在 $_ 中有某些我能启动的好东西吗"。如果我们想要, 我们甚至能自己设置 $_

sub seek-the-answer() {
    $_ = (^100).pick;
    when 42 { say "The answer" }
    default { say "A number"   }
}

换句话说, 我们已经知道了 whengiven 是单独的。Switch 语句逻辑都在 when 语句中。

第二个小改变: 你可以嵌套 when 语句!

我很确信你没有在野外见过这种用法。但它有时候特别有用:

when * > 2 {
    when 4  { say 'Four!' }
    default { say 'huge'  }
}
default {
    say 'little'
}

你可能记得, 在 when 块儿中有一个隐式的 succeed 语句在末尾, 这让周围的主题化块退出。(意思是你不必记着手动退出 switch 语句)。 如果你想重写 succeed 语句并继续通过 when block, 那么你在 when block 的末尾写上一个显式的 proceed 即可。

given $verse-number {
    when * >= 12 { say "Twelve drummers drumming"; proceed }
    when * >= 11 { say "Eleven pipers piping"; proceed }
    # ...
    when * >= 5 { say "FIIIIIIVE GOLDEN RINGS!"; proceed }
    when * >= 4 { say "Four calling birds"; proceed }
    when * >= 3 { say "Three French hens"; proceed }
    when * >= 2 {
        say "Two turtle doves";
        say "and a partridge in a pear tree";
    }
    say "a partridge in a pear tree";
}

given 和 when 是正交的, 意味着你可以单独使用 given、单独使用 when、given/when 同时使用。

given 42 { .say; .Numeric; } # 42

这比下面这个等价的表达式更易读:

{ .say; .Numeric; }(42) # 42

given 作为语句

given 可以跟着一个语句以在它跟着的语句中设置主题(topic)。

.say given "foo";
# OUTPUT
# «foo
»

printf "%s %02i.%02i.%i", 
    [.day-of-week - 1], 
    .day,
    .month,
    .year 
    given DateTime.now;
# OUTPUT«Sa 03.06.2016»

你可能感兴趣的:(Perl 6 中的 given-when)