java 为什么在“if x then return”之后很少使用“else”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3261849/
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
Why is "else" rarely used after "if x then return"?
提问by Todd Owen
This method:
这种方法:
boolean containsSmiley(String s) {
if (s == null) {
return false;
}
else {
return s.contains(":)");
}
}
can equivalently be written:
可以等价地写成:
boolean containsSmiley(String s) {
if (s == null) {
return false;
}
return s.contains(":)");
}
In my experience, the second form is seen more often, especially in more complex methods (where there may be several such exit points), and the same is true for "throw" as well as "return". Yet the first form arguably makes the conditional structure of the code more explicit. Are there any reasons to prefer one over the other?
根据我的经验,第二种形式更常见,尤其是在更复杂的方法中(可能有几个这样的退出点),“throw”和“return”也是如此。然而,第一种形式可以说使代码的条件结构更加明确。有什么理由更喜欢一个吗?
(Related: Should a function have only one return statement?)
(相关:一个函数应该只有一个返回语句吗?)
回答by Delan Azabani
The elsein that case would be redundant, as well as create unnecessary extra indentation for the main code of the function.
在else这种情况下是多余的,以及对功能的主要代码创建不必要的额外缩进。
回答by Brendan Long
In my experience, it depends on the code. If I'm 'guarding' against something, I'll do:
根据我的经验,这取决于代码。如果我在“防范”某事,我会这样做:
if (inputVar.isBad()) {
return;
}
doThings();
The point is clear: If that statement is false, I don't want the function to continue.
重点很明确:如果该陈述是错误的,我不希望该函数继续运行。
On the other hand, there are some functions with multiple options, and in that case I would write it like this:
另一方面,有些函数有多个选项,在这种情况下,我会这样写:
if (inputVar == thingOne) {
doFirstThing();
} else if (inputVar == secondThing) {
doSecondThing();
} else {
doThirdThing();
}
Even though it could be written as:
尽管它可以写成:
if (inputVar == thingOne) {
doFirstThing();
return;
}
if (inputVar == thingTwo) {
doSecondThing();
return;
}
doThingThree();
return;
It really comes down to which way most clearly shows what the code is doing (not necessarily which bit of code is shortest or has the least indentation).
它实际上归结为最清楚地显示代码正在做什么的方式(不一定哪位代码最短或缩进最少)。
回答by Eugene Yokota
This is a pattern called Guard Clause. The idea is do all the checking upfront to reduce nested conditions to increase readability.
这是一种称为Guard Clause的模式。这个想法是预先进行所有检查以减少嵌套条件以提高可读性。
From the link:
从链接:
double getPayAmount() {
double result;
if (_isDead) {
result = deadAmount();
} else {
if (_isSeparated) {
result = separatedAmount();
} else {
if (_isRetired) {
result = retiredAmount();
} else {
result = normalPayAmount();
}
}
}
return result;
}
Using the Guard Clause, you'll get to see this result:
使用 Guard Clause,您将看到以下结果:
double getPayAmount() {
if (_isDead) return deadAmount();
if (_isSeparated) return separatedAmount();
if (_isRetired) return retiredAmount();
return normalPayAmount();
};
回答by amphetamachine
You will see this all over:
你会看到这一切:
if (condition) {
return var;
}
// by nature, when execution reaches this point, condition can only be false,
// therefore, the else is unnecessary
return other_var;
Most of the time the addition of an else clause is not only unnecessary in this case, but a lot of times, it gets optimized awayby the compiler.
大多数情况下,在这种情况下添加 else 子句不仅是不必要的,而且很多时候,它会被编译器优化掉。
Think of how the computer thinks of this code (in terms of machine code, simplified into pseudocode here for demonstration purposes):
想一想计算机是如何看待这段代码的(机器码方面,这里简化为伪代码用于演示):
0x00: test [condition]
0x01: if result of test was not true, goto [0x04]
0x02: push [var] onto stack
0x03: goto [0x05]
0x04: push [other_var] onto stack
0x05: return from subroutine
The code (again, this is a pseudocode and not assembly) would act the exact same way for an if/then/elseconditional.
代码(同样,这是一个伪代码而不是程序集)对if/then/else条件的作用完全相同。
It is, by many people, considered bad and/or confusing practice to have multiple possible exit points for a function, as a programmer must think of every possible path through his code. Another practice is the following:
许多人认为一个函数有多个可能的退出点是不好的和/或令人困惑的做法,因为程序员必须考虑通过他的代码的每一个可能的路径。另一种做法如下:
return (condition) ? var : other_var;
This simplifies the code, and does not create any new exit points.
这简化了代码,并且不会创建任何新的退出点。
回答by ChaosPandion
I prefer writing it like this:
我更喜欢这样写:
boolean containsSmiley(String s) {
return s != null && s.contains(":)");
}
回答by drekka
Like any "discussion" about coding styles there is no correct answer. I prefer to apply these considerations:
就像任何关于编码风格的“讨论”一样,没有正确的答案。我更愿意应用这些考虑因素:
Does the code work as expected in all situations. (Principle of least surprise)
Can the next developer (myself or someone else) understand what it is doing and why.
How fragile is the code with respect to change.
Is is simple as it needs to be and no more. I.e. no over or under engineering.
代码是否在所有情况下都按预期工作。(最小惊喜原则)
下一个开发人员(我自己或其他人)能否理解它在做什么以及为什么。
代码在更改方面有多脆弱。
Is 很简单,因为它需要,仅此而已。即没有超过或低于工程。
Once I'm happy that I have satisfied the above, the rest generally just falls falls into line.
一旦我很高兴我已经满足了上述要求,其余的通常就顺理成章了。
回答by yaskovdev
I would prefer the first option, as it is more human-readable.
我更喜欢第一个选项,因为它更具人类可读性。
As an analogy, compare the next 2 sentences: "If today is raining, then take an umbrella, else take sunglasses." and "If today is raining, then take an umbrella, take sunglasses". The first sentence corresponds to the first block of code from the question, the second one – to the second. The first one is much more clear and readable, isn't it?
打个比方,比较接下来的两句话:“如果今天下雨,那就带把伞,否则带上太阳镜。” 和“如果今天下雨,那就带把伞,带上太阳镜”。第一句对应于问题的第一个代码块,第二个 – 到第二个。第一个更清晰易读,不是吗?
回答by fwielstra
Someone else probably noted this already, but I'd recommend against using null values in general where strings are expected. If you really want a check to prevent someone passing null values, you can use asserts (at dev time) or unit tests (deploy):
其他人可能已经注意到这一点,但我建议不要在需要字符串的地方使用空值。如果您真的想要检查以防止有人传递空值,您可以使用断言(在开发时)或单元测试(部署):
boolean containsSmiley(String s) {
assert s != null : "Quit passing null values, you moron.";
return s.contains(":)");
}
I've switched to a general rule of thumb: Never. Ever. pass null values, unless an external API calls explicitly asks for it. Second: If an external method may return null values, replace it with a sensible non-null value (such as an empty string) or add a neat check. I grow sick of repetitive if (thing == null)checks.
我已经改用一般的经验法则:从不。曾经。传递空值,除非外部 API 调用明确要求它。第二:如果外部方法可能返回空值,请将其替换为合理的非空值(例如空字符串)或添加整洁的检查。我厌倦了重复if (thing == null)检查。
But that's a bit offtopic. I like putting short conditions on top and guard clauses, removing elses if program flow dictates it'll never get there.
但这有点题外话。我喜欢在 top 和 guard 子句上放置简短的条件,如果程序流规定它永远不会到达那里,则删除 elses。
回答by fwielstra
Cause it's nicer. You know you could also use '{' '}' to create several levels of nesting, but nobody really does it for just the heck of it.
因为更好看 您知道您也可以使用 '{' '}' 来创建多个级别的嵌套,但没有人真的只是为了它而这样做。
回答by Juha Syrj?l?
The elseis redundant. Also some IDEs (Eclipse) and analysis tools (maybe FindBugs) may flag that as a warning or an error, so in that case programmers are likely to remove it.
该else是多余的。此外,某些 IDE (Eclipse) 和分析工具(可能是 FindBugs)可能会将其标记为警告或错误,因此在这种情况下,程序员可能会将其删除。

