是“if(...)return ...;”没有“else”认为好风格? [英] Is an "if(...) return ...;" without "else" considered good style?

查看:214
本文介绍了是“if(...)return ...;”没有“else”认为好风格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码:

  if(someCondition)
return doSomething

return doSomethingElse();

与此代码相比:

  if(someCondition)
return doSomething();
else
return doSomethingElse();

实质上,他们是一样的,但什么是最好的风格/性能/ ...有没有任何非意见部分的答案当然)?也考虑多个if else's的情况:

  if(someCondition)
return doSomething
else if(someOtherCondition)
return doSomethingDifferently();
// ...
else
return doSomethingElse();


$ b

谢谢!

解决方案

当函数中有多个return语句时,这被称为early return。如果您 Google搜索



我说废话。



有两个主要原因和一个次要原因,人们声称早期回报是坏的。我会经历他们,并按顺序给我反驳。请记住这是我的意见,最终你必须自己决定。



1)原因:早期回报很难清理。



反驳:这就是 RAII 的用途。精心设计的程序不会以这样的方式分配资源,即如果执行过早抛弃范围,那么这些资源将泄漏。而不是这样做:



...

  int foo )
{
MyComplexDevice * my_device = new MyComplexDevice;
// ...
if(something_bad_hapened)
return 0;
// ...
delete my_device;
return 42;
}

您可以这样做:

  int foo()
{
std :: auto_ptr< MyComplexDevice> my_device(new MyComplexDevice);
if(something_bad_hapened)
return 0;
// ...
return 42;
}

早期返回不会导致资源泄露。在大多数情况下,你甚至不需要使用 auto_ptr ,因为你将创建数组或字符串,在这种情况下,你会使用 vector string 或类似的东西。



无论如何,你应该像这样设计你的代码,因为可能会出现异常。异常是一种早期返回的形式,如一个显式的 return 语句,您需要准备好处理它们。你不能处理 foo()中的异常,但是 foo()

2)原因:早期回报使代码更复杂。
反驳:早期回报实际上使代码更简单。



这是一个共同的哲学,功能应该有一个责任。我同意。但是人们把这个太远,并得出结论,如果一个函数有多个返回,它必须有一个以上的责任。 (他们延长这一点,说功能永远不应超过50行长,或一些其他任意数字。)我说不。只是因为一个函数只有一个责任,并不意味着它不需要做很多工作来完成那个可重用性。



以打开数据库为例。这是一个责任,但它是由许多步骤组成,每个步骤可能会出错。打开连接。登录。获取连接对象&把它返还。 3个步骤,每个步骤都可能失败。你可以把它分成3个子步骤,但是代替这样的代码:

  int foo b $ b {
DatabaseObject db = OpenDatabase(...);
}

您最终会得到:

  int foo()
{
Connection conn = Connect(...);
bool login = Login(...);
DBObj db = GetDBObj(conn);
}

所以你真的只是把多个职责移到更高的位置调用堆栈。



3)原因:多个返回点不是面向对象的。
Rebuttal:这真的只是另一种说法:每个人都说多个回报是坏的,虽然我真的不知道为什么。



,这真的只是一个试图把一切都放在一个物体形状的盒子里,即使它不属于那里。当然,也许连接是一个对象。但是是登录?登录尝试不是(IMO)对象。它的操作。或算法。试图采取这种算法并将其绑定到一个对象形状的盒子是一个无尽的尝试在OOP,并且只会导致更复杂,更难维护,甚至可能更低效的代码。


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( someCondition )
    return doSomething();
else if( someOtherCondition )
    return doSomethingDifferently();
//...
else
    return doSomethingElse();

Thanks!

解决方案

When you have multiple return statements in a function, this is referred to as "early return." If you do a Google search for "early return" you will find link after link that says it is bad.

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.

Rebuttal: That's what RAII is 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:

...

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.

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.

2) Reason: Early returns make code more complex. Rebuttal: Early returns actually make code simpler.

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.

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:

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."

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.

这篇关于是“if(...)return ...;”没有“else”认为好风格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆