【问题标题】:Nested if statements vs extra else if?嵌套 if 语句与额外的 else if?
【发布时间】:2023-03-29 01:06:01
【问题描述】:

我遇到了很多逻辑工作,我不确定哪种设计模式更适合 if 语句。在这些情况下,我通常可以放入一个嵌套的 if 语句,或者替代地。这两种情况如下所示。两者各有优劣,有没有应该遵循的标准?

if (val > 0 && is_on)
{
  // (1)
}
else if (val > 0)
{
  // (2)
} 
else
{
  // (3)
}
if (val > 0)
{
  if(is_on)
  {
    // same as (1)
  }
  else
  {
    // same as (2)
  }
}
else
{
  // same as (3)
} 

【问题讨论】:

    标签: if-statement logic language-agnostic


    【解决方案1】:

    我认为任何方法都没有任何特定的优点或缺点。这一切都取决于您希望如何设计代码以及您认为第一次查看您的代码的人更容易阅读的内容。

    在我看来,第一种方法看起来更好,因为它更可读并且包含更少的代码行。

    【讨论】:

      【解决方案2】:

      第一种方法更具可读性。但是随着逻辑表达式(例如“val > 0 && is_on”)变得更长,合并到第二种方法开始变得更有意义。第二个更容易调试,所以你可以从那里开始然后合并回来。我最终会匹配周围代码/“代码策略”的风格。

      【讨论】:

        【解决方案3】:

        虽然其他答案绝对正确,因为您的主要关注点应该是可读性,但我想解决另一个区别:执行性能。

        在第一个示例中,在else 分支可以运行之前需要评估两个条件。如果随着我们扩展这个 else/if 阶梯中的条件数量,到达else 分支的评估量线性增长。现在,我们并不期望有一万个条件或任何东西,但仍然需要注意。

        现在,在您的第二个示例中,我们检查前两个分支之间的共同条件,如果失败,我们将快速失败到 else 分支,无需额外测试。在极端情况下,这有点类似于对正确代码块的二进制搜索——左右分支直到找到匹配项,而不是逐个检查每个顺序的线性扫描。

        现在,这是否意味着您应该使用后者?不一定——可读性更重要,如果你用编译语言编写,编译器可能会优化掉所有这些。即使您使用的是解释性语言,与其他所有内容相比,性能影响也可能可以忽略不计,除非这是热循环的热部分。

        但是,如果您对第一个示例中重复的“浪费”感到困扰,但宁愿避免大量嵌套,语言通常会提供 赋值表达式 语法,为您提供第三个选项,您计算一次结果并将其存储到内联变量中,以便在后续代码中重用。

        例如:

        if (expensive_func1() > 0 && is_on)
        {
          // (1)
        }
        else if (expensive_func1() > 0 && expensive_func2() > 0)
        {
          // (2)
        } 
        else
        {
          // (3)
        }
        

        变成:

        if ((is_alive = expensive_func1() > 0) && is_on)
        {
          // (1)
        }
        else if (is_alive && expensive_func2() > 0)
        {
          // (2)
        } 
        else
        {
          // (3)
        }
        

        这使我们免于重新计算条件之间的公共子表达式,在语言中我们不能依赖编译器来为我们做这件事。当然,我们可以在 if 语句之前明确地将这些分配给变量,但是我们咬紧牙关评估所有共享表达式,而不是根据需要懒惰地评估它们(假设我们计算 expensive_func2 > 0 以便在第三个 if/else 中重用,只是发现我们不需要它,我们正在使用第一个分支)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-08-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多