Is it bad style to use return at the beginning of a function to avoid doing unnecessary work?
假设我们有一个函数foo()和一个bool条。如果bar为false,foo所做的工作将毫无用处。写foo()最合适的方法是什么?
一
1 2 3 4 5 | foo() { if(!bar) return; doWork(); } |
二
1 2 3 4 | foo() { if(bar) doWork(); } |
选项1的美学优势是dowork()(即函数的其余部分)不缩进,但缺点是,如果不查看早期返回语句,则可以假定每次调用foo()时都调用dowork()。
一般来说,用样式1编码是不好的做法,还是应该是个人偏好?
样式1对于保护声明非常有用。这样地:
1 2 3 4 5 6 | void work() { if (!something) return; //do the job } |
否则,我会说这取决于情况。如果
有些人总是会对你说"有一个单一的出口点"的咒语。
有时,如果您需要对每个出口点执行特定的操作,这很有意义。我想说,在这种情况下,保持清醒是至关重要的。
现在,如果您没有这个需求,我个人认为,只要您尽快退出并保持代码的识别级别较低,就没有问题。
我见过有人用do包装整个代码……}while(0);block只保留单个出口点规则,使用break而不是return。这让我发疯。但在某些情况下,它可能是一个有用的设备。
总的来说,使用常识,在你的具体问题上使用更有意义的东西。
我的2分价值:如果你保持你的函数很小,多次返回不是一个真正的问题。在大型函数(可能需要重构,但有时不重构)中,多个返回语句(尤其是嵌套控制结构中的)开始表现得像goto,这使得函数更难解释。
这是一种个人偏好,非常主观——你很可能会看到很多关于这方面的意见。嗯,这两种款式都没有问题。每个都以合理的方式显示控制流,选项1实际上在检查某些功能参数等方面非常有用。
对函数进行编码的正确方法是有一个入口点和一个出口点。这样做可以更容易地维护和调试应用程序。根据您的示例,您应该使用所呈现的第二种样式编写代码:
1 2 3 4 | foo() { if(bar) doWork(); } |