当我在我的代码上运行ReSharper时,例如:
if (some condition)
{
Some code...
}
Run Code Online (Sandbox Code Playgroud)
ReSharper给了我上面的警告(反转"if"声明以减少嵌套),并提出了以下更正:
if (!some condition) return;
Some code...
Run Code Online (Sandbox Code Playgroud)
我想明白为什么那样更好.我一直认为在方法中间使用"返回"有问题,有点像"goto".
我长期以来一直认为,goto如果可能的话,永远不应该使用它.在前几天阅读libavcodec(用C语言编写)时,我注意到它的多种用途.goto在支持循环和函数的语言中使用是否有利?如果是这样,为什么?
我不时会用一个while(1)块来压扁一连串if..else不成比例的东西.它沿着这些方向发展.
而不是做:
// process
if (success) {
// process
if (success) {
//process
if (success) {
// etc
}
}
}
Run Code Online (Sandbox Code Playgroud)
我做:
while (1) {
// process
if (!success) break;
// process
if (!success) break;
// process
if (!success) break;
// etc
break;
}
Run Code Online (Sandbox Code Playgroud)
我对这个结尾的隐含跳跃感到有些恼火while.我能用更精简的构造逃脱(即最后没有break)吗?
我可以break用变量(或寄存器?)来交易最终结果.这不是更精简或更清晰.
int once = 1;
while (once--) {
// process
if (!success) break;
// process
if (!success) break;
// process
if (!success) break;
// etc …Run Code Online (Sandbox Code Playgroud) 我对如何最好地将我的代码重构为更具可读性的东西感到困惑.
考虑一下这段代码:
var foo = getfoo();
if(foo!=null)
{
var bar = getbar(foo);
if(bar!=null)
{
var moo = getmoo(bar);
if(moo!=null)
{
var cow = getcow(moo);
...
}
}
}
return;
Run Code Online (Sandbox Code Playgroud)
如您所见,需要大量嵌套if块,因为每个嵌套块依赖于先前的值.
现在我想知道如何让我的代码在这方面更清洁一些.
我自己想到的一些选择是:
ArgumentNullExceptions,之后我将它们捕获到最后并将return语句放在我的finally子句中(或者在try/catch块之外)goto:大多数这些选项对我来说似乎有点"脏",所以我想知道是否有一种很好的方法来清理我创建的这个混乱.
假设我有一些c ++代码:
if (error)
goto exit;
...
// size_t i = 0; //error
size_t i;
i = 0;
...
exit:
...
Run Code Online (Sandbox Code Playgroud)
我知道我们不应该使用goto,但仍然为什么
size_t i;
i = 0;
Run Code Online (Sandbox Code Playgroud)
编译而size_t i = 0;不是?
为什么标准强制执行此类行为(由@SingerOfTheFall提及)?
可以转换为块,但不能以初始化绕过声明的方式.从具有自动存储持续时间的局部变量不在范围内的点跳转到其在范围内的点的程序是不正确的,除非该变量具有POD类型(3.9)并且在没有初始化器的情况下声明.
当代码流是这样的:
if(check())
{
...
...
if(check())
{
...
...
if(check())
{
...
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
我一般都看到这个工作,以避免这个混乱的代码流:
do {
if(!check()) break;
...
...
if(!check()) break;
...
...
if(!check()) break;
...
...
} while(false);
Run Code Online (Sandbox Code Playgroud)
有哪些更好的方法可以避免这种变通/破解,从而使其成为更高级别(行业级别)的代码?
是否有可能来自Apache commons或Google Guava的构造?
注意:这是C++相同问题的副本.最好的答案是真正的函数指针和GOTO命令.两者都不存在于Java中.我对Java的同样兴趣很感兴趣.
将它放入一个新函数并使用return在我看来不是一个好的解决方案,因为return退出了该方法.因此,如果我的类有20个方法使用这些结构,我将不得不添加20个额外的方法来完成这个.这就是为什么GOTO是C++的最佳答案.
如果在代码中有许多if子句并且代码的执行在先前的错误中是不明智的,那么使用单周期循环是否可以?只是为了能够休息时退出街区?像这样:
do {
//..code
if (error1) break;
//..code
if (errorN) break;
//do finally something when no errors before
} while (false);
Run Code Online (Sandbox Code Playgroud) 我知道很多问题,例如为什么不使用goto,为什么goto不好用,为什么是goto由恶魔创造的,为什么goto要敲打打字者的手指等?
在对这个问题,这个问题甚至在Wikipedia的许多答案中,都有可能找到赞成或反对的理由goto。
甚至Stackoverflow也有一个goto标签:)
但是,显然,它goto被接受为有效命令,否则您的编译器/解释器将不知道如何处理它。即使在C / C ++中,也可以使用goto,并且该语言甚至具有正式的ISO规范。
因此,大概在某些情况下,只有通过使用goto它才能完成某些任务。那么,为什么以及何时goto在C / C ++中使用a ?
编辑:
只想确认一下:
1-这个问题不需要辩论。应该是负责任的:给出一个或多个goto唯一解决方案的情况,或说明no, it's always possible to avoid a goto。当然,我不是唯一可以决定是否关闭它的人,但是我不认为“范围太广,要求辩论等”是关闭它的理由。
2-在某些情况下,goto可以使代码更整洁,更快等。我不希望如此。我想知道是否存在goto唯一的解决方案(不,这不是“给出goto的好例子”问题的重复)
3-如果有正当理由,我将接受任何不赞成票,脸上带着微笑。但是我很确定这个问题已经解决了,并且已经对该主题进行了先前的研究。拒绝投票很简单,因为使用了以“ G”开头的4字母禁忌词...对不起...
嗨,如果使用goto是优化的好习惯,我会徘徊.我知道这是一个野蛮的事情,但是,认真的.
比如写这个:
switch(command[0].cmd)
{
case 0: // turn off
s::s_off();
S_time = command[0].length;
break;
case 1: // turn on
s::s_on();
S_time = command[0].length;
break;
case 4: // nop
break;
}
Run Code Online (Sandbox Code Playgroud)
像这样:
switch(command[0].cmd)
{
case 0: // turn off
s::s_off();
goto a;
break;
case 1: // turn on
s::s_on();
goto a;
break;
case 4: // nop
goto b;
break;
}
a:
S_time = command[0].length;
b:
Run Code Online (Sandbox Code Playgroud)