【问题标题】:Better way to use if condition更好的使用 if 条件的方法
【发布时间】:2013-09-01 07:55:59
【问题描述】:

我需要运行一个包含 10 多个条件的测试脚本来验证。如果任何步骤失败,则程序将失败并且不会执行进一步的步骤。目前,我的程序是这样的:

boolean status = 0;

status = function1(param1, param2);
if (status) {
   status = function2(param1, param2);
   if(status) {
      status = function3(param1, param2);
      if(status) {
         status = function4(param1, param2);
      }
      :
      :
      :
   }
} 

return status;

我对这么多嵌入的 IF 子句不满意。有更好的方法吗?

【问题讨论】:

  • 所有的印记怎么了?

标签: perl if-statement coding-style


【解决方案1】:

翻译成Perl,你可以这样写:

sub testing
{
    my $status;

    if (($status = function1($param1, %param2)) &&
        ($status = function2($param1, %param2)) &&
        ($status = function3($param1, %param2)) &&
        ($status = function4($param1, %param2)))
    {
        # ...do whatever...
    }

    return $status;
}

或者,鉴于 $status 只是一个布尔值:

sub testing
{
    return 0 if !function1($param1, %param2) ||
                !function2($param1, %param2) ||
                !function3($param1, %param2) ||
                !function4($param1, %param2);

    # ...do whatever...

    return 1;
}

或者:

sub testing
{
    return 0 unless function1($param1, %param2);
    return 0 unless function2($param1, %param2);
    return 0 unless function3($param1, %param2);
    return 0 unless function4($param1, %param2);
    # ...do whatever...
    return 1;
}

如果您真的有 10 个具有相同调用签名的函数,那么您甚至可以这样做:

sub testing
{
    my @funcs = ( &function1, &function2, &function3, &function4, &function5,
                  &function6, &function7, &function8, &function9, &function10,
                );

    for my $funcref (@funcs)
    {
        return 0 unless &$funcref($param1, %param2);
    }

    # ...do whatever...

    return 1;
}

请注意,前三个替代方案将处理不同的函数调用签名,只是代码布局更加混乱;最后一个几乎需要列表中每个函数的相同函数调用签名。

【讨论】:

  • 我不喜欢 if() 中的多个作业。第二个例子还可以,也许func() or die/return在perl中更常见
  • 很公平。鉴于更高版本,我也不喜欢第一个版本。并在问题中给出,该值是一个布尔值,您可以避免分配并简单地测试函数返回值。
【解决方案2】:
return function1($param1, %param2) &&
       function2($param1, %param2) &&
       function3($param1, %param2) &&
       function4($param1, %param2);

只要其中一个函数返回 false 值,它就会使用 short-circuit 停止评估。

【讨论】:

    【解决方案3】:

    记住&&是短路的,这意味着在下面的语句中

    func1 && func2
    

    如果func1 评估为假,则永远不会评估func2,因为此后&& 永远不会为真。

    这意味着您可以在没有任何 if 子句的情况下复制您的功能:

    return func1 && func2 && func3 ...
    

    【讨论】:

      【解决方案4】:

      我想再提一个选项:

      通过=真

      通过=通过 && cond1 通过=通过 && cond2 ... 如果(通过)...

      【讨论】:

        【解决方案5】:

        另一个避免所有嵌套但与原始选项相似的选项:

        boolean status = 0;
        
        status = function1(param1, param2);
        if (status) {
            status = function2(param1, param2);
        }
        if (status) {
            status = function3(param1, param2);
        }
        if (status) {
            status = function4(param1, param2);
        }
        

        这种样式允许轻松添加更多调用和轻松重新排序。

        【讨论】:

        • 它将完成所有步骤。从技术上讲,这不是最有效的方法。
        • @ericyoung 你是对的,但是现代计算机担心优化一些测试可能是在浪费人们的时间。更重要的是理解和维护程序的能力。最初的问题要求编写代码的更好方法,我相信这在某些方面更好。
        • @AdiranHHH 你是对的。它比其他方法更清洁。我希望我能选择一个以上的正确答案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多