例如,当我在我的代码上运行ReSharper时:
if (some condition)
{
Some code...
}
ReSharper给了我上面的警告(反转“if”语句以减少嵌套),并建议以下更正:
if (!some condition) return;
Some code...
我想知道为什么这样更好。我一直认为在方法中间使用“return”是有问题的,有点像“goto”。
例如,当我在我的代码上运行ReSharper时:
if (some condition)
{
Some code...
}
ReSharper给了我上面的警告(反转“if”语句以减少嵌套),并建议以下更正:
if (!some condition) return;
Some code...
我想知道为什么这样更好。我一直认为在方法中间使用“return”是有问题的,有点像“goto”。
当前回答
从理论上讲,反转if可以提高分支预测的命中率,从而提高性能。在实践中,我认为很难确切地知道分支预测将如何表现,特别是在编译之后,所以我不会在日常开发中这样做,除非我正在编写汇编代码。
更多关于分支预测的信息。
其他回答
这完全是有争议的。在提前返回的问题上,“程序员之间没有达成一致”。据我所知,这总是主观的。
这是有可能的,因为最好有条件,所以它们通常是真的;也可以说,它更清晰。另一方面,它确实创建了嵌套测试。
我不认为你会对这个问题得到一个结论性的答案。
方法中间的返回并不一定是坏的。如果能使代码的意图更清晰,那么立即返回可能会更好。例如:
double getPayAmount() {
double result;
if (_isDead) result = deadAmount();
else {
if (_isSeparated) result = separatedAmount();
else {
if (_isRetired) result = retiredAmount();
else result = normalPayAmount();
};
}
return result;
};
在这种情况下,如果_isDead为真,我们可以立即退出该方法。也许这样结构会更好:
double getPayAmount() {
if (_isDead) return deadAmount();
if (_isSeparated) return separatedAmount();
if (_isRetired) return retiredAmount();
return normalPayAmount();
};
我从重构目录中挑选了这段代码。这种特殊的重构被称为:用保护子句替换嵌套条件句。
我的想法是“在函数中间”的返回不应该那么“主观”。 原因很简单,以下面的代码为例:
function do_something( data ){ if (!is_valid_data( data )) return false; do_something_that_take_an_hour( data ); istance = new object_with_very_painful_constructor( data ); if ( istance is not valid ) { error_message( ); return ; } connect_to_database ( ); get_some_other_data( ); return; }
也许第一个“回报”不是那么直观,但这是真正的储蓄。 有太多关于干净代码的“想法”,只是需要更多的实践来摆脱他们“主观的”坏想法。
这里有几个很好的观点,但如果方法非常冗长,多个返回点也可能是不可读的。也就是说,如果你打算使用多个返回点,只要确保你的方法是简短的,否则多个返回点的可读性奖励可能会丢失。
它不仅美观,而且还减少了方法内部的最大嵌套级别。这通常被认为是一个优点,因为它使方法更容易理解(事实上,许多静态分析工具提供了一种度量方法,作为代码质量的指标之一)。
另一方面,它还使您的方法具有多个退出点,另一组人认为这是不可取的。
就我个人而言,我同意ReSharper和第一组(在有例外的语言中,我发现讨论“多个退出点”是愚蠢的;几乎任何东西都可能抛出,所以在所有方法中都有许多潜在的退出点)。
关于性能:每种语言的两个版本都应该是等效的(如果不是在IL级别,那么肯定是在代码抖动结束后)。从理论上讲,这取决于编译器,但实际上,今天任何广泛使用的编译器都能够处理比这更高级的代码优化情况。