Unnecessary 'else' statement
如您所知,在Eclipse中,您可以打开"不必要的"else"语句"检查,该检查将触发if-then-else并提前返回。根据我的经验,在使用这种声明时,有两种最可能的情况:
1)预检查:
1 2 3 4 | if (!validate(arg1)) { return false; } doLotOfStuff(); |
2)事后检查:
1 2 3 4 5 6 | doLotOfStuff(); if (condition) { return foo; } else { return bar; } |
在第二种情况下,如果触发器打开,Eclipse将建议您将代码更改为:
1 2 3 4 5 | doLotOfStuff(); if (condition) { return foo; } return bar; |
但是,我认为使用else语句返回更具可读性,因为它类似于业务逻辑的直接映射。所以我很好奇,如果这种"不必要的"else"语句的代码约定很普遍,或者用else语句的代码更可取?
通常,我希望代码的结构遵循底层"业务"逻辑的结构。在这种情况下,我的方法将取决于
1 2 3 4 5 | doLotOfStuff(); if (condition) { return foo; } return bar; |
但是,如果这两种可能性都是合理的,而且只是它们之间的一种选择,我会允许代码的结构显示这种对称性。
1 2 3 4 5 6 | doLotOfStuff(); if (condition) { return foo; } else { return bar; } |
代码是供程序员阅读的,而不是编译器。
曾经有人认为(可能还有人认为)函数应该有一个入口点(很容易,但在考虑汇编语言时是相关的)和一个出口点。
从调试的角度来看,一个退出点是很好的(就像你可以在一条线上放一个手表/手表,并知道你会经历它),但可能会导致一些可怕的嵌套,因此经常会比不可读性更容易获胜。哪个产生最少的嵌套、最少的代码行和最可读的最终结果?最终,这比其他任何事情都重要得多。
就其价值而言,最后一个可以更好地表示为:
1 | return condition ? foo : bar; |
假设
不要过分关注所谓的代码"纯度"。这是不相干的干扰。使事物可读,并且通常保持一致。
好的,一些著名的Java专家争辩说,一个人应该总是尽量减少事情的范围,这也是我的观点。
我在大学的老师总是让我苦恼,我必须写一些以前有人发的这样的东西:
1 2 3 4 5 6 7 8 | String result = null; doLotOfStuff(); if (condition) { result = foo; } else { result = bar; } return result; |
变量结果现在有一个很大的范围。此外,如果您在这里做得更多一些,比如说您有另一个for循环,那么对于很多嵌套来说,这会变得非常不可读。
我觉得这样好多了:
1 2 | doLotOfStuff(); return condition ? foo : bar; |
这是直截了当的。我马上就知道发生了什么,没有检查大括号。
我觉得很好
- 最小化范围
- 最小化缩进(即避免使用大括号)
- 最小化方法长度
"多余的else语句"警告对此有所帮助。
我找到这个表格了
1 2 3 4 5 | doLotOfStuff(); if (condition) { return foo; } return bar; |
要比使用其他代码的代码更易读,如果您像Fowler的重构一样将其看作一个保护语句,那么它的代码更少,而且更直观。
关于多个返回点的问题。
嗯,我认为使用多重返回是不可读的。
我喜欢代码为:
1 2 3 4 5 6 7 8 9 10 | String result = null; doLotOfStuff(); if (condition) { result = foo; } else { result = bar; } return result; |
多重回报很难理解。但对你来说,我更喜欢后验
1 2 3 4 5 6 | doLotOfStuff(); if (condition) { return foo; } else { return bar; } |
我知道,如果没有IDE为我检查这个,我几乎总是使用不必要的else语句。通常我发现它一开始读起来更好,但当它被指出时,通常会删除它,因为我可以看到这是不必要的事实,然后它会让我抓狂…
在我看来,Eclipse检查不是很有用。您应该做什么取决于您的程序上下文。else子句是可选的(不管是这个还是那个),而陷入返回(没有其他子句)是更合适的,因为您有许多条件可能是真的,而fallthrough更像是一个默认反应,您不经常调用。因此,在代码中同时使用这两种方法来传递意义,因此检查是否存在是没有用的。
叫我坏孩子,但我通常会:
1 2 | doLotOfStuff(); return condition ? foo : bar; |
单返回语句,可读性强。
如果跟踪以下代码,我会注意到第一个if块是一个异常的代码块。但是,如果我在其中添加一个"else",我可能会认为这两个都是可操作的代码块。
另外,对于主操作块,可能有一些嵌套的块。我更喜欢最小化嵌套级别。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public String myMethod(input) { if (!validate(input)) { return"invalid input"; } operation1(); if (someCondition) { operation2(); } else { operation3(); } operation4(); operation5(); return operation6(); } |
一些程序员声称,处于函数中间的