如何制作这些嵌套if条件的更好代码

时间:2013-03-02 07:17:18

标签: perl coding-style nested-if

我有一个像这样的嵌套式代码

 if (condition1 or condition2 or condition3 ) {
           if  (condition1) {
           }
           elsif (condition2) {
           }
           elsif (condition3) {
           }
 }

现在很明显,条件(1,2和3)已在外if上检查,因此我不希望在内if-elsif语句中再次检查它们。 所以我的解决方案是,完全删除外部if。但是,这将使它通过if-elsif

那么如果有10-15个条件怎么办呢。哪一个更好?或者还有其他更好的解决方案吗?

6 个答案:

答案 0 :(得分:3)

外部if是不必要的。

除此之外,只有三种可能的优化似乎是合理的:

  1. 在优化之前对代码进行分析,并对if / else条件进行排序,以便首先测试最常见的条件等。
  2. 使用数据结构来表示条件。如果您要测试某种等式(if ($foo eq $bar){...}elsif($foo eq $baz){...}),那么哈希可以将查找从线性转换为常量时间:

    %hash = ($bar => sub{...}, $baz => sub{...});
    my $code = $hash{$foo} or do{"this is the trailing else"};
    $code->(); # execute the coderef
    

    这非常灵活,但包括闭包的间接。

  3. 如果必须重新检查条件,请缓存结果。在条件中声明的变量的范围会到达if / else链的所有后续条件和块:

    if ( my $cond1 = ... and ...) {
      ...
    } elsif ($cond1 and my $cond2 = ...) {
      ...
    } elsif ($cond2) {
      ...
    }
    

答案 1 :(得分:2)

这取决于您的代码执行的频率。对于复杂的if语句集,最好优化可读性,因为与大多数其他操作相比,它们便宜。但是,在上面的示例中,我将完全删除外部语句,这根本就没有必要。无论如何,Perl会在解析代码时优化代码。

答案 2 :(得分:2)

如果您的条件都是对同一变量值的测试,则可以在Perl 5.10.1及更高版本中使用given / when

use 5.010;

given ($foo) {
  when ('bar') { ... }                  # string literal
  when (4) { ... }                      # numeric literal
  when (qw[ xyzzy plugh ]) { ... }      # any of multiple literals
  when (/^whee+$/) { ... }              # regex match
  default { ... }                       # fallthrough if nothing matched
}

答案 3 :(得分:1)

也许Switch控制语句可能在你的代码中有意义(取决于你正在检查的条件)。看看documentation of Switch

<强>更新 从5.10 perl版本开始,有一个given/when control flow

 use feature "switch";

答案 4 :(得分:0)

  1. 删除外部if语句,因为内部if语句无论如何都会检查所有条件。

  2. 如果根据条件1优先安排哪些if条件比条件2更重要,那么当然,您无法更改支票的顺序。

  3. 如果您根据发生的频率安排了哪些if条件,那么您可以在测试或分析程序时根据频率重新排列。

  4. 如果condition1为true,则运行statement1。如果你的陈述太长,那么把它们放入子程序并调用它们,这样看起来就更整洁了。

    if    (condition1) {&run_statement1();}
    elsif (condition2) {&run_statement2();}
    elsif (condition3) {&run_statement3();}
    elsif (condition4) {&run_statement4();}
    elsif (condition5) {&run_statement5();}
    elsif (condition6) {&run_statement6();}
    elsif (condition7) {&run_statement7();}
    else               {&run_elsestatement();}
    
  5. 不要不必要地使代码复杂化或混淆。保持简单,可读并实现您的目标。

答案 5 :(得分:0)

或者这个:

(condition1) ? run_statement1() :
(condition2) ? run_statement2() :
(condition3) ? run_statement3() : run_elsestatement() ;

我喜欢不那么打字。如果您的评估条件产生“唯一”结果,则另一个选项是将结果用作函数散列中的键。这将完全取消上面的条件检查。

例如,如果条件基于名为'$ var'的标量中的值,那么您可以简单地使用这些不同的值作为哈希的键。

$conditionalFunctionHash{$var}->();