C++ 是“if(...) return ...;” 没有“其他”被认为是好的风格?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4238063/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is an "if(...) return ...;" without "else" considered good style?
提问by rubenvb
This code:
这段代码:
if( someCondition )
return doSomething();
return doSomethingElse();
versus this code:
与此代码相比:
if( someCondition )
return doSomething();
else
return doSomethingElse();
In essence, they are the same, but what is best style/performance/... (if there is any non-opinionated part to the answer of course)? Also consider the case with multiple "if else's":
从本质上讲,它们是相同的,但是什么是最佳风格/性能/...(当然,如果答案有任何非自以为是的部分)?还要考虑多个“if else's”的情况:
if( someCondition )
return doSomething();
else if( someOtherCondition )
return doSomethingDifferently();
//...
else
return doSomethingElse();
Thanks!
谢谢!
回答by John Dibling
When you have multiple return statements in a function, this is referred to as "early return." If you do a Google searchfor "early return" you will find link after link that says it is bad.
当您在一个函数中有多个 return 语句时,这称为“提前返回”。如果您在Google 上搜索“提前退货”,您会发现一个又一个链接说它不好。
I say nonsense.
我说废话。
There are two primary reasons and one secondary reason that people claim that early return is bad. I'll go through them and give my rebuttal in order. Keep in mind this is all my opinion and ultimately you have to decide for yourself.
人们声称提前退货不好有两个主要原因和一个次要原因。我会仔细阅读它们并按顺序进行反驳。请记住,这是我的全部意见,最终您必须自己决定。
1) Reason: Early returns make it difficult to clean up.
1)原因:提前退货,清理难度大。
Rebuttal: That's what RAIIis for. A well-designed program won't allocate resources in such a way that if a the execution leaves scope early those resources will leak. Instead of doing this:
反驳:这就是RAII的用途。一个设计良好的程序不会以这样一种方式分配资源,即如果执行提前离开范围,这些资源就会泄漏。而不是这样做:
...
...
int foo()
{
MyComplexDevice* my_device = new MyComplexDevice;
// ...
if( something_bad_hapened )
return 0;
// ...
delete my_device;
return 42;
}
you do this:
你做这个:
int foo()
{
std::auto_ptr<MyComplexDevice> my_device(new MyComplexDevice);
if( something_bad_hapened )
return 0;
// ...
return 42;
}
And early return won't cause a resource leak. In most cases, you won't even need to use auto_ptr
because you'll be creating arrays or strings, in chich case you'll use vector
, string
or something similar.
并且提前返回不会造成资源泄漏。在大多数情况下,您甚至不需要使用,auto_ptr
因为您将创建数组或字符串,在特殊情况下您将使用vector
,string
或类似的东西。
You should design your code like this anyway for robustness, because of the possibility of exceptions. Exceptions are a form of early return like an explicit return
statement, and you need to be prepared to handle them. You may not handle the exception in foo()
, but foo()
should not leak regardless.
无论如何,为了健壮性,您应该像这样设计代码,因为存在异常的可能性。异常是一种类似显式return
语句的提前返回形式,您需要准备好处理它们。您可能不会处理 中的异常foo()
,但foo()
无论如何都不应泄漏。
2) Reason: Early returns make code more complex. Rebuttal: Early returns actually make code simpler.
2)原因:早期返回使代码更复杂。反驳:早期返回实际上使代码更简单。
It is a common philosophy that functions should have one responsibility. I agree with that. But people take this too far and conclude that if a function has multiple returns it must have more than one responsibility. (They extend this by saying that functions should never be more than 50 lines long, or some other arbitrary number.) I say no. Just because a function has only one responsibility, doesn't mean it doesn't have a lot to do to fulfil that resposibility.
功能应该有一个责任是一种普遍的哲学。我同意这一点。但人们对此太过分了,并得出结论,如果一个函数有多个返回值,那么它必须承担多个责任。(他们通过说函数的长度不应超过 50 行或其他任意数字来扩展这一点。)我说不。仅仅因为一个功能只有一个责任,并不意味着它没有很多事情要做来履行这个责任。
Take for example opening a database. That's one responsibility, but it is made up of many steps, each of which could go wrong. Open the connection. Login. Get a connection object & return it. 3 steps, each of which could fail. You could break this down in to 3 sub-steps, but then instead of having code like this:
以打开数据库为例。这是一个责任,但它由许多步骤组成,每个步骤都可能出错。打开连接。登录。获取连接对象并返回它。3 个步骤,每个步骤都可能失败。您可以将其分解为 3 个子步骤,但不要使用这样的代码:
int foo()
{
DatabaseObject db = OpenDatabase(...);
}
you'll end up having:
你最终会得到:
int foo()
{
Connection conn = Connect(...);
bool login = Login(...);
DBObj db = GetDBObj(conn);
}
So you've really just moved the supposed multiple responsibilities to a higher point in the call stack.
所以你真的只是将假定的多重职责移到调用堆栈中的更高点。
3) Reason: Multiple return points are not object-oriented. Rebuttal: This is really just another way of saying "everybody says multiple returns are bad, though I don't really know why."
3)原因:多个返回点不是面向对象的。反驳:这实际上只是“每个人都说多重回报不好,尽管我真的不知道为什么”的另一种说法。
Taken another way, this is really just an attempt to cram everything in to an object-shaped box, even when it doesn't belong there. Sure, maybe the connection is an object. But is the login? A login attempt isn't (IMO) an object. Its an operation. Or an algorithm. trying to take this algorithm and cram it in to an object-shaped box is a gratuitous attempt at OOP, and will only result in code that is more complex, harder to maintain, and possibly even less efficient.
换句话说,这实际上只是试图将所有东西都塞进一个物体形状的盒子里,即使它不属于那里。当然,也许连接是一个对象。但是是登录吗?登录尝试不是 (IMO) 对象。它的一个操作。或者算法。试图将这个算法塞进一个对象形状的盒子是 OOP 的一种无端尝试,只会导致代码更复杂、更难维护,甚至可能效率更低。
回答by Puppy
A function should always return as soon as possible. This saves semantic overhead in unnecessary statements. Functions that return as soon as possible offer the highest clarity and the cleanest, most maintainable source code.
函数应该总是尽快返回。这节省了不必要语句中的语义开销。尽快返回的函数提供了最高的清晰度和最干净、最易于维护的源代码。
SESE-style code was good when you had to manually write to free every resource you had allocated, and remembering to free them all in several different places was a waste. Now that we have RAII, however, it's definitely redundant.
当您必须手动编写以释放已分配的每个资源时,SESE 风格的代码是很好的,而记住在几个不同的地方释放它们是一种浪费。然而,现在我们有了 RAII,它绝对是多余的。
回答by fredoverflow
It's purely a matter of personal preference or coding standards. Personally, I would prefer a third variant:
这纯粹是个人喜好或编码标准的问题。就个人而言,我更喜欢第三种变体:
return someCondition ? doSomething() : doSomethingElse();
回答by Kiril Kirov
It depends, I prefer the same as FredOverflow
这取决于,我更喜欢和 FredOverflow 一样
return someCondition ? doSomething() : doSomethingElse();
If this is enough. If it isn't, I have wondered for a similar situation - if you have longer code - lets say 30-40 lines or more, should I put return;
on a place, that's not necessary. For example, consider the following situation:
如果这足够了。如果不是,我想知道类似的情况——如果你有更长的代码——比如说 30-40 行或更多,我应该放在return;
一个地方,那是没有必要的。例如,请考虑以下情况:
if( cond1 )
{
if( cond2 )
{
// do stuff
}
else if( cond3 )
{
// ..
}
}
else if( cond4 )
{
// ..
}
else
{
//..
}
What I wondered was - should I put return;
(in void function) at the end of each case - is this a good or bad coding style (as it doesn't matter if there's return;
or not). Finally I decided to put it, because the developer, who'll read this code later, to know that this is a final state and there's nothing to be done anymore in this function. Not to read the rest of the code, if he/she's interesting only in this case.
我想知道的是 - 我应该return;
在每个案例的末尾放置(在 void 函数中) - 这是一种好的还是坏的编码风格(因为有与没有无关紧要return;
)。最后我决定放它,因为稍后会阅读此代码的开发人员知道这是一个最终状态,并且此功能不再需要做任何事情。不要阅读其余的代码,如果他/她只在这种情况下感兴趣。
回答by Cheers and hth. - Alf
It depends.
这取决于。
If you're following a convention of early returns to handle error cases then that's good, if you're just doing arbitrary things then it's bad.
如果您遵循早期返回的约定来处理错误情况,那很好,如果您只是在做任意的事情,那就不好了。
The most serious problem with the code as presented is that you're not using curly braces. That means not quite understanding what clarity's about. If not for that I'd just answer your main question with "aim for clarity", but first you need to understand clarity. As first step on that road, start using curly braces. Try to make your code readable by others, so much so that it can be understood at-a-glance by someone else (or by yourself months/year later).
所呈现的代码最严重的问题是您没有使用花括号。这意味着不太明白什么是清晰度。如果不是这样,我只会用“以清晰为目标”来回答您的主要问题,但首先您需要了解清晰。作为这条道路的第一步,开始使用花括号。尽量让你的代码对其他人可读,以至于其他人(或几个月/一年后的你自己)可以一目了然地理解它。
Cheers & hth.,
干杯 & hth.,