鉴于以下代码段,是否有明显的区别?

public boolean foo(int input) {
   if(input > 10) {
       doStuff();
       return true;
   }
   if(input == 0) {
       doOtherStuff();
       return true;
   }

   return false;
}

VS.

public boolean foo(int input) {
   if(input > 10) {
      doStuff();
      return true;
   } else if(input == 0) {
      doOtherStuff();
      return true;
   } else {
      return false;
   }
}

还是单个代码在这里会更好...

public boolean foo(int input) {
   boolean toBeReturned = false;
   if(input > 10) {
      doStuff();
      toBeReturned = true;
   } else if(input == 0) {
      doOtherStuff();
      toBeReturned = true;
   }

   return toBeReturned;
}

是否有明显的性能差异?您是否觉得一个或多或少的可维护/可读性?

有帮助吗?

解决方案

在第二个示例中,您非常清楚地表明,这两种情况都是相互排斥的。
对于第一个,这并不清楚,在(不太可能)的事件中,分配给 input 在两个IF之间都添加,逻辑将会改变。
假设将来有人添加 input = 0 在第二个之前。
当然,这不太可能发生,但是如果我们在这里谈论可维护性,如果埃尔斯清楚地说,有相互排斥的条件,而一堆IF则不像不那么依赖-Else块。

编辑:现在,在这个特定示例中,我看到了返回子句迫使相互排他性,但是同样,我们正在谈论可维护性和可读性。

无论如何,关于性能,如果在Java中进行了编码,则您不应该关心几个IF块的性能,如果将其嵌入了C中,则可能是非常缓慢的硬件,但肯定不会使用Java。

其他提示

使用最能描述您意图的任何形式。

如果事情很简单,请不要遵循单个退出原则,这只是使其更加混乱。

  • 在第一个:

    最终,某人出于某种奇怪的原因,当您不寻找的时候会添加一些添加陈述,使该方法在某些奇怪的条件下失败,每个人(或最坏,一个人)将花费4小时。观看源代码并调试应用程序,以最终发现中间有些东西。

  • 第二个绝对更好,不仅可以防止这种情况,而且还有助于清楚地陈述 或者 这是另一个 不再。

    如果我们在 if 如果最多有10行长,这并不重要,但是不幸的是,情况并非如此,还有其他程序员,这些程序员在某种原因上认为,如果身体应该长度> 200行长……无论如何。

  • 我不喜欢第三个,它迫使我寻找返回变量,并且更容易找到 return 关键词

关于速度性能,它们几乎是相同的。不用担心。

在您的最后一个示例中,不要这样做:

public boolean foo(int input) {
   boolean toBeReturned = false;
   if(input > 10) {
      doStuff();
      toBeReturned = true;
   } else if(input == 0) {
      doOtherStuff();
      toBeReturned = true;
   }

   return toBeReturned;
}

但这(请注意Java的使用 最终的):

public boolean foo(int input) {
   final boolean toBeReturned;    // no init here
   if(input > 10) {
      doStuff();
      toBeReturned = true;
   } else if(input == 0) {
      doOtherStuff();
      toBeReturned = true;
   } else {
      toBeReturned = false;
   }
   return toBeReturned;
}

通过这样做,您可以清楚自己的意图,这是支持“通过意图进行编程”的IDE的天赐之物(无需“编译”才能看到潜在的错误,即使在部分AST中,好的IDE也可以在现实中检查不完整的来源。时间并立即警告)。

这样你就是 当然 不要忘记初始化您的返回值。如果稍后您决定毕竟您需要另一个条件,这真是太好了。

自从我开始使用Intellij Idea(很久以前的4版左右)以来,我一直都这样做,甚至是Moreso,这为我节省了很多愚蠢的干扰错误...

有人会争辩说,对于这种简单的情况来说,这是太多的代码 Tobereturn 而且,您可能会忘记从以后的子句中返回,您可能会添加。

否则,如果“简洁”是游戏的名称,那么我会写:

public boolean foo(int a) {
  return a > 10 ? doStuff() : a == 0 ? doOtherStuff() : false; 
}

两者都在哪里 做东西Dootherstuff 会返回真。

语义上 - 不。在性能方面,这取决于编译器,即是否可以发现两种情况都不能立即发现。我敢打赌标准的太阳编译器可以。是否使用单一出口原则取决于口味。我个人讨厌它。

版本#1和#2可能比#3快,但我想性能差异很小。我宁愿专注于 可读性.

就个人而言,我永远不会使用版本2。在#1和#3之间,我会选择为所讨论的情况产生最可读的代码的一个。我不喜欢方法中的许多出口点,因为它使代码难以分析。但是,在某些情况下,当我们立即在某些特殊情况下退出时,流动变得更清晰,并继续进行主要案例。

想想这两个示例不相似的情况:

    public boolean foo(int input) {
        if (input > 10) {
            // doStuff();
            return true;
        }
        System.out.println("do some other intermediary stuff");
        if (input == 0) {
            // doOtherStuff();
            return true;
        }

        return false;
    }

VS.

    public boolean foo(int input) {
        if (input > 10) {
            // doStuff();
            return true;
        } 
        //System.out.println("doing some intermediary stuff... doesn't work");
        else if (input == 0) {
            // doOtherStuff();
            return true;
        } else {
            return false;
        }
        return false;
    }

第一种方法可能是 更灵活, ,但两者兼而有之 公式 在不同情况下使用它们。

关于性能,我认为对于任何常规的Java应用程序,由SANE程序员编码为:)。

在您的情况下,第二次仅在第一次失败时才会被调用,因此在这里不太重要,但是如果您的第一个命令做某事并没有返回,则第二次(当时将始终为false)仍会进行测试,除非它进行测试在其他人中。

换句话说,在某些情况下,如果if-else-if和if-之间的差异很重要,但这不是其中之一。

示例:尝试此操作,然后在删除其他方面尝试一下。您将获得两个不同的输出:

int someNumber = 1;
if(someNumber < 5)
{
    someNumber += 5;
    Console.WriteLine("First call.");
}
else if(someNumber >= 5)
{
    Console.WriteLine("Second call.");
}

在第一和第二片段之间,确实没有区别。但是,第三个片段效率很低。因为您要等待将程序控制返回到呼叫者,直到方法中的最后一行代码为止,因此您浪费了处理能力/内存,而前两个代码片段一旦确定了一个条件之一,请立即返回控制。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top