从子例程结束循环的迭代

Car*_*eVS 7 perl loops subroutine

我有一个带有while循环的程序,它有几个点,某些条件需要采取某些操作,然后跳过剩余的迭代.

因为这总是相同的代码,我想把它放在子程序中,但当我尝试使用'next;'时 作为子中的最后一个语句,我得到一个警告(通过下一个退出子程序......),虽然它似乎按预期工作.

即没有子:

while (#condition) {

    ## do stuff

    if (#condition to skip iteration) {
        ## action
        next;
    }

    ## do more stuff, with the above block repeated several times
}
Run Code Online (Sandbox Code Playgroud)

与子:

while (#condition) {

    ## do stuff

    &skip if (#condition to skip iteration);

    ## do more stuff, with more calls to &skip
}

sub skip() {
    ## action
    next;
}
Run Code Online (Sandbox Code Playgroud)

块/子中的其余代码是如此之短以至于除了下一个之外的所有代码; sub中的语句几乎违背了使用子例程的对象.

我的问题是:

  • 正在使用'next;' 以这种方式在子程序中好,还是危险/差的做法?
  • 有没有更好的方法从子例程跳过剩余的迭代?
  • 如果没有问题并且没有更好的方法,有没有办法抑制警告?

tob*_*ink 9

很容易抑制警告.只需将以下行放在您的上方next:

no warnings "exiting";
Run Code Online (Sandbox Code Playgroud)

警告是有原因的 - next在辅助子中使用这样可能会让下一个必须阅读代码的人感到困惑(可能是你在6个月之后!)因为next在循环块内没有词汇发生.如果您只是阅读循环块,您可能不会注意到next文件的下方; 如果你只是阅读子程序的定义,你可能不确定那next是什么.您需要一起阅读代码的两个部分才能理解它.这使得它比next直接在循环中使用更令人困惑.

此外,它限制了skip()您刚刚定义的子的重新可用性.想skip()在另一个循环中重用那个子?你最好希望跳过逻辑在新循环中仍然有意义.

如果您已经考虑了所有这些并且仍然希望继续,那么只需禁用上面显示的警告.警告不是错误,它们只是警告.这就是为什么警告被称为"警告".它们旨在将您的注意力集中在可能存在问题的事物上; 不要阻止你做你认为有用的事情.


jm6*_*666 6

来自Learning perl第6版第179页(脚注)

这可能不是一个好主意,但你可以在子程序中使用这些循环控制操作符来控制子程序之外的循环.也就是说,如果在循环程序段中调用子程序,并且子程序在子程序内没有运行循环程序段时最后执行,则控制流将跳转到主代码中的循环程序段之后.这种在子程序中使用循环控制的能力可能会在未来的Perl版本中消失,没有人可能会错过它.

解决方案可能是其他人已经说过的,或者你可以在sub中进行额外的测试,比如

use strict;
use warnings;

while(<>) {
    chomp;
    maybeskip($_) && next if m/2/; #maybe skip if match 2
    print "$_\n";
}

sub maybeskip {
    $_[0] !~ m/0/; #skip only if not match 0
    # the sub retuns the result of the last executed expression
    # if this is not wanted you should use explicit return $value;
}
Run Code Online (Sandbox Code Playgroud)

为了

seq 25 | perl script
Run Code Online (Sandbox Code Playgroud)

打印:

1
3
4
5
6
7
8
9
10
11
13
14
15
16
17
18
19
20
Run Code Online (Sandbox Code Playgroud)

例如,跳过所有匹配2但不是20


thb*_*thb 4

你的警告本能可能是对的。正如您所说,nextjust 不是嵌入子程序中的那种语句。即使您不喜欢它,这几乎肯定会更好:

while (#condition) {

    ## do stuff

    &skip, next if (#condition to skip iteration);

    ## do more stuff, with more calls to &skip
}

sub skip() {
    ## action
}
Run Code Online (Sandbox Code Playgroud)

(我碰巧对非标准编程技术持相当宽松的态度​​,特别是如果它们没有被过度使用的话。如果您强烈希望next在这种情况下嵌入 ,那么我不会与您争论,因为这是您的程序。但是,尽管如此,既然您已经询问了建议,我同意您的直觉,即嵌入next可能不是一个好主意。)