【问题标题】:What are the conditions under which one can use a 'when' statement in Perl 5?在 Perl 5 中可以使用“when”语句的条件是什么?
【发布时间】:2013-07-05 01:40:27
【问题描述】:

关于given 块之外的when 语句的文档似乎很少。据说when 可以在设置“主题”时使用,但究竟什么时候考虑设置了主题?考虑以下情况:

for (@arr) {
  when { }
}

似乎这是默认的基本情况,但我什至无法在我的 perl 5.14.2 上使用它 - $ perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print 'boom'} }' 什么也没打印。我做错了什么?原来这只是另一个 bash 引用问题。

for my $elem (@arr) {
  when { }
}

这行得通吗? $elem 会自动成为when 使用的主题吗?

for (@arr) {
  $_ = some_expression($_);
  when { }
}

这行得通吗?可以在循环内设置主题吗?

另外,当上面的每个代码段使用foreach而不是for时,有什么区别吗?

基本上,我对主题的主题非常不清楚,所以请赐教。

【问题讨论】:

    标签: perl for-loop foreach


    【解决方案1】:

    这是一个shell命令构造错误。

    perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print 'boom'} }'
    

    应该是

    perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print '\''boom'\''} }'
    

    我们可以切换成双引号来简化

    perl -Mfeature=switch -le'foreach (qw(a b c)) { when (/a/) {print "boom"} }'
    

    我们可以进一步简化

    perl -E'for (qw(a b c)) { when (/a/) { say "boom" } }'
    

    关键字forforeach 与Perl 相同。

    请注意,5.18 将 givenwhen 标记为实验性版本。它不会消失,但会改变。我解释了发生了什么here


    不,when 不使用$elem;它总是使用$_


    是的,如果您愿意,您可以在forgiven 中更改$_。请注意,foreach 循环将它们的主题别名为正在访问的元素,因此更改一个会更改另一个。

    my @x = qw( abc def );
    for (@x) { $_ = uc($_); }
    say @x;  # ABCDEF
    

    【讨论】:

    • 我的引号总是出错,谢谢。感谢您提供其他答案的链接,该链接以及那里的链接有助于更好地了解状态。我对此有一个奇怪的情况:perl -E '@arr = qw(a b c); foreach $x (@arr) { $_=$x; $_++; when (/b/) {print $x} }' 它按预期打印 a ,但随后似乎因错误“无法在 -e 第 1 行的主题化器之外使用 when() ”而死。如果我用 $_ 删除两行,相同的代码运行没有错误(但不打印)。你能解释一下这里发生了什么吗?
    • @sundar,问题不在于引号的选择。问题是你没有正确地逃避它们。查看更新。
    • 这种转义 ' 的语法对我来说是新的和有用的,谢谢。关于主题化,这就是为什么我提到“如果我用 $_ 删除这两行,相同的代码运行不会出错”。似乎任何 for/foreach 循环都被视为主题化程序,即使对于 SOMETHING (...) 循环也是如此,但是在循环内分配给 $_ 会以某种方式搞砸。
    • 这不是因为你在循环中做某事。只有当when 成功(即$_ ~~ /b/ 为真)时,您才会被告知错误,而且它恰好有一次成功。试试perl -E'$_="b"; for my $x ("b") { when (/b/) { } }'。如果SOMETHING 不为空、$_my $_our $_state $_,则不允许使用for SOMETHING (...) { ... when ... }
    • 哦,为什么when 工作一次但以后不行?你能解释一下这背后的逻辑吗?我只是想了解整个情况。感谢您花时间反复澄清事情,谢谢。
    【解决方案2】:

    池上发现了你的实际问题。关于其他问题:

    两个主题词是for/foreachgiven。设置$_(主题变量)的其他构造不被视为主题化器(例如mapgrep)。

    如果您使用显式循环变量运行 foreach 循环,则该循环不会被视为主题化器。因此,

    for my $x (1..3) {
      local $_ = $x;
      say when 2;
    }
    

    将适用于第一次迭代,但一旦退出 when,就会死掉(不能在主题化器之外“当”)。

    given 的不同之处在于它不会本地化$_,而是给出一个词法$_。也就是说,given (@a) { foo; }{ my $_ = \@a; foo; } 相似(我认为这可能是固定的)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-08
      • 2022-08-17
      • 1970-01-01
      • 1970-01-01
      • 2011-10-04
      • 2019-04-08
      • 2014-01-23
      相关资源
      最近更新 更多