是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?

或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?


当前回答

在一个没有副作用的函数中,没有理由有多个返回值,你应该用函数式的风格来编写它们。在有副作用的方法中,事情更有顺序(时间索引),因此您使用命令式风格编写,使用return语句作为停止执行的命令。

换句话说,如果可能的话,尽量采用这种风格

return a > 0 ?
  positively(a):
  negatively(a);

在这

if (a > 0)
  return positively(a);
else
  return negatively(a);

如果您发现自己编写了几层嵌套的条件,可能有一种方法可以重构它,例如使用谓词列表。如果您发现If和else在语法上相差很大,您可能希望将其分解为更小的函数。跨越超过一屏文本的条件块很难阅读。

没有适用于每一种语言的严格规则。像只有一个return语句这样的东西不会使你的代码好。但是好的代码将允许您以这种方式编写函数。

其他回答

如果可以只写下一个观点,那就是我的观点:

我完全不同意“单返回语句理论”,认为它在代码可读性、逻辑和描述方面都是推测性的,甚至是破坏性的。

使用一次-一次返回的习惯对于纯过程式编程来说都很糟糕,更不用说更高级的抽象(函数式、组合式等)了。此外,我希望所有以这种风格编写的代码都经过一些特殊的重写解析器,使其具有多个返回语句!

一个函数(如果它真的是一个函数/查询,根据“查询-命令分离”注意-见埃菲尔编程语言。例如)必须定义与控制流场景一样多的返回点。它在数学上更加清晰和一致;它是编写函数(即查询)的方法。

但对于你的特工收到的突变信息——程序调用,我不会那么激进。

我想说,武断地决定不使用多个出口点是非常不明智的,因为我发现这种技术在实践中一次又一次地有用,事实上,为了清晰起见,我经常将现有的代码重构为多个出口点。我们可以这样比较这两种方法:-

string fooBar(string s, int? i) {
  string ret = "";
  if(!string.IsNullOrEmpty(s) && i != null) {
    var res = someFunction(s, i);

    bool passed = true;
    foreach(var r in res) {
      if(!r.Passed) {
        passed = false;
        break;
      }
    }

    if(passed) {
      // Rest of code...
    }
  }

  return ret;
}

将此与允许多个出口点的代码进行比较

string fooBar(string s, int? i) {
  var ret = "";
  if(string.IsNullOrEmpty(s) || i == null) return null;

  var res = someFunction(s, i);

  foreach(var r in res) {
      if(!r.Passed) return null;
  }

  // Rest of code...

  return ret;
}

我认为后者要清楚得多。据我所知,现在对多个退出点的批评是一种相当过时的观点。

函数中return语句越多,该方法的复杂性就越高。如果您发现自己想知道是否有太多的return语句,那么您可能需要问问自己,该函数中是否有太多的代码行。

但是,不是,一个/多个返回语句并没有错。在某些语言中,这是一种比其他语言(C)更好的实践(c++)。

由于错误处理,您已经隐式地拥有多个隐式返回语句,因此要处理它。

但是,就像编程中的典型情况一样,有支持和反对多次返回实践的例子。如果它能让代码更清晰,那就这样做。使用许多控制结构会有所帮助(例如case语句)。

没有人提到或引用代码完成,所以我就这么做。

17.1返回

尽量减少每个例程的返回次数。如果在底部阅读一个例程,你没有意识到它可能会返回到上面的某个地方,那么理解它就更难了。

在增强可读性时使用返回。在某些例程中,一旦知道了答案,就希望立即将其返回给调用例程。如果例程以不需要任何清理的方式定义,则不立即返回意味着必须编写更多代码。