7

重复: 一个函数应该只有一个返回语句吗?

很多时候,您可能有一个方法可以检查多个条件并返回一个状态(现在让我们说布尔值)。定义一个标志,在方法期间设置它,并在最后返回它是否更好:

boolean validate(DomainObject o) {
  boolean valid = false;
  if (o.property == x) {
     valid = true;
  } else if (o.property2 == y) {
     valid = true;
  } ...
  return valid; 
}

还是在您知道方法的结果后简单地返回更好/更正确?

boolean validate(DomainObject o) {

  if (o.property == x) {
     return true;
  } else if (o.property2 == y) {
     return true;
  } ...
  return false; 
}

现在显然可能有 try/catch 块和所有其他类型的条件,但我认为这个概念很清楚。意见?

4

10 回答 10

12

如果这是一种您将调用数千次的方法,那么尽早返回更好地实现[略微]提高的性能。

如果没有,那么我更喜欢延迟返回,因为它提高了可读性。

请记住,程序员通常花在阅读上的时间多于编写代码的时间,因此您可以做任何提高可读性的事情肯定会受到欢迎。

于 2009-05-19T18:59:38.820 回答
12

我更喜欢早点返回并避免深度嵌套。在方法开始时尤其如此:测试任何简单的东西,如果可以尽早退出(或抛出异常)。

如果它正好在一个方法的中间,它更像是一个判断调用。

请注意,我会立即重构您的示例以使用单个if

boolean validate(DomainObject o) {    
  if (o.property == x || o.property2 == y) {
     return true;
  } ...
  return false; 
}

我意识到这只是一个玩具示例,但我的观点是,寻找更多简化代码的方法总是值得的 :)

于 2009-05-19T19:00:59.893 回答
6

与大多数编码风格一样,这实际上是一个偏好问题,但许多人认为保护子句是最佳实践。

于 2009-05-19T18:58:42.723 回答
4

我唯一会说你绝对不应该提前返回的情况是,如果你不能轻易地在一个屏幕上看到每个返回(无论标准对于使用相同代码库的人来说可能是什么),你至少应该是添加注释表明如果有提前返回,该函数可以提前返回。

唯一一次我会说你绝对应该早点回来是如果你的代码看起来像......

boolean valid = true;
if( condition1 ) {
   valid = false;
}
if( valid ) {
   ...
   if( condition2 ) {
      valid = false;
   }
}
if( valid ) {
   ...
   if( condition3 ) {
      valid = false;
   }
}
... (etc)

但是,如果您发现自己处于上述任何一种情况……您可能应该重构该函数。

于 2009-05-19T19:07:45.857 回答
3

对我来说,这是一种没有正确答案的宗教战争话题。反对提前返回的论点基本上归结为这样一个事实,即只有一个函数可以退出的点减少了通过代码的可能路径的数量,因此,至少在理论上,减少了错误的机会。我的个人风格是,在提前返回有意义的情况下这样做,并且在限制为一个返回声明有意义的情况下我这样做。

于 2009-05-19T18:58:36.000 回答
2

有两个因素相互拉扯。

第一个因素是易于调试。如果您立即返回(如您的第二个代码片段所示),有时很难调试一个大函数,因为很难找到这些返回语句,特别是如果它们被错误地放在那里。

第二个因素是易于实施。如果您在函数开头检查参数的基本正确性,并且在函数完成之前有一段很长的代码,您可能必须将整个代码放入条件循环中。如果你不这样做,在某些时候,这个论点可能会被用于一些长时间的计算,浪费时间,因为它最终还是会被拒绝。

所以,答案可能是这样的:

If the function is small, 
        save the return status in a variable and return at the end. 
else 
        return immediately.
于 2009-05-19T19:06:35.373 回答
1

如果异常不是图片的一部分,我宁愿在可能的情况下立即返回。

标志变量管理不善很容易,我通常反对标志变量。不返回也可能使维护者认为可能会做进一步的工作(如果方法很长)。

于 2009-05-19T18:59:44.763 回答
0

就个人而言,我更喜欢第二种方法。这对我来说很简单明了,但我确实知道有些人在函数中必须只有一个返回值。

于 2009-05-19T18:58:38.277 回答
0

老实说,我认为这取决于情况。就我个人而言,我同时使用这两种方法,并根据哪一种来使代码更清晰易读。

如果您有大量嵌套的 if 语句(或任何其他控制结构)并且它可能会让人感到困惑,那么我会在语句中返回

在这种情况下,不要太担心什么是“最佳实践”,因为更重要的是代码清晰易懂。使用适合情况的方法。

于 2009-05-19T19:00:41.237 回答
0

对于这种情况,我更喜欢:

boolean validate (DomainObject o) {
    if (o.property == x ||
        o.property2 == y ||
        ...) {
          return true;
    } else {
          return false;
}

一般来说,我喜欢使用提前返回来处理错误情况,并在结束时返回来返回计算结果。

于 2009-05-19T19:04:38.967 回答