为啥我的继续执行 Perl 5.10 中的下一个 when 块?

Posted

技术标签:

【中文标题】为啥我的继续执行 Perl 5.10 中的下一个 when 块?【英文标题】:Why doesn't my continue execute the next when block in Perl 5.10?为什么我的继续执行 Perl 5.10 中的下一个 when 块? 【发布时间】:2010-03-29 16:27:58 【问题描述】:

当我运行这个时:

use feature ':5.10';
$x=1;
given ($x) 
    when(1) 
        say '1';
        $x = 2;
        continue;
    
    when (2) 
        say '2';
    

这应该打印 1 和 2,但它只打印 1。我错过了什么吗?

编辑:

我添加了 $x = 2,但它仍然只打印“1”

【问题讨论】:

为什么期望它输出2? $x 是 1。 查看我的编辑...仍然无法正常工作 这不起作用,因为given$x 复制到$_,这是智能匹配的参数。如果您在第一个when 中设置$_ = 2,它将起作用。 FWIW,我在 Learning Perl, Fifth Edition 中展示了一个扩展示例来解决这个问题。 :) 另外,对于任何在家玩的人,请使用 5.10.1。智能匹配在 5.10.0 中被破坏。 【参考方案1】:

参见perlsyn 手册页:

given(EXPR) 将在块的词法范围内将 EXPR 的值赋给 $_

此代码输出 1 和 2:

use feature ':5.10';
$x=1;
given ($x) 
    when(1) 
        say '1';
        $_ = 2;
        continue;
    
    when (2) 
        say '2';
    

【讨论】:

【参考方案2】:

我认为您可能误解了 continue 的目的或 switch 构造中的 fallthrough 的性质。

每个when 块都以隐式中断结束,因此given 在成功匹配后退出。 continue 所做的只是告诉given 块继续处理when 条件而不是突破。它不会强制下一个 when 条件神奇地为真,而不是。

考虑一下,确实输出两次。

use feature ':5.10';
$x=1;
given ($x) 
    when(1) 
        say '1';
        continue;
    
    when ( /1/ ) 
        say '1 again';
    

【讨论】:

我认为我误解的根源是 C,其中 "switch" 中的失败不会做任何额外的测试......它只是失败并执行下一个块。【参考方案3】:

由于 given 不是循环构造(尽管它支持 continue,在该实例中是特殊情况),所以使用 foreach 或 for 类似的:

use feature ':5.10';
$x=1;
for ($x) 
    when(1) 
        say '1';
        $x = 2;
        continue;
    
    when (2) 
        say '2';
    

for (expression) 将 $_ 设置为表达式,并且该行为在某些情况下用于在给定/何时之前模拟 switch。

【讨论】:

以上是关于为啥我的继续执行 Perl 5.10 中的下一个 when 块?的主要内容,如果未能解决你的问题,请参考以下文章

在linux下的如何将perl默认版本5.8.8升级为5.10

继续而不是 Perl 中的“或死”

高效 pre-perl-5.10 等效于 pack("Q>")

哪里有学习 Perl 5.10 新特性的好资源?

我可以确保在 5.10+ 上编写的 Perl 代码可以在 5.8 上运行吗?

Perl 5.10 - POSIX 信号被忽略,除非在 sleep() 调用期间收到?