I don't think I'd write in this way in the first place, but going along with the premise, I'm guessing that any compiler would crank out the same code whichever method you chose to write, so there is no technical reason that I can think would favour one over the other.
The argument is therefore Single or Compound statement.
I think the rule of "least surprise" should be used, which in this case would call FOR the superfluous else statements to be included.
PS. I would always send a temperature in degrees centigrade, oops, just broke your function!
Dim Temp As Integer
Dim Message As String
Select Case Temp
Case Is < 32
Message = "Freezing"
Case Is < 60
Message = "Just Right"
Case Is < 80
Message = "Too Hot"
Case Else
Message = "What was I doing?"
End Select
我发现这些语句比 if..else 语句更容易阅读。
I prefer case statements myself but that would make this a language specific topic and not language-agnostic topic.
Dim Temp As Integer
Dim Message As String
Select Case Temp
Case Is < 32
Message = "Freezing"
Case Is < 60
Message = "Just Right"
Case Is < 80
Message = "Too Hot"
Case Else
Message = "What was I doing?"
End Select
I find these alot easier to read then if..else statements.
public String getTemperatureMessage(double temp) {
String result;
if(temp < 32) {
result = "Freezing";
} else {
if(temp < 60) {
result = "Brr";
} else {
if(temp < 80) {
result = "Comfortable";
} else {
result = "Too hot";
}
}
}
return result;
}
It depends on a lot of things like how complex your code is. With a simple example like this, I'd put the returns on the same line as the ifs, and not use elses. The structure and behaviour is clear:
When I have more complex code I find it useful to not break out from the nesting with returns or continue/break, but to assign to state or result variables. I will then also include {} even if the block is a single statement, mostly to keep the consistency in how the structure is represented in code, but also to slightly reduce the risk that later edits will forget to change a statement to a block.
If this example was more complex, I'd probably code it like this:
public String getTemperatureMessage(double temp) {
String result;
if(temp < 32) {
result = "Freezing";
} else {
if(temp < 60) {
result = "Brr";
} else {
if(temp < 80) {
result = "Comfortable";
} else {
result = "Too hot";
}
}
}
return result;
}
int do_something(int arg1)
{
if (arg1 > MAX_ARG1_VALUE)
return ARG1_ERROR;
... main guts of code here
return 0;
}
例如,我认为说:比说:
int do_something(int arg1)
{
if (arg1 > MAX_ARG1_VALUE)
return ARG1_ERROR;
else
{
... main guts of code here
return 0;
}
}
或
int do_something(int arg1)
{
if (arg1 <= MAX_ARG1_VALUE)
{
... main guts of code here
return 0;
}
else
return ARG1_ERROR;
,如果有多个事情可能“出错”,那么这种区别就变得尤其重要,例如
int do_something(int arg1)
{
if (arg1 > MAX_ARG1_VALUE)
return ARG1_ERROR;
... some code goes here
if (something_went_wrong1)
return SOMETHING1_ERROR;
... more code goes here
if (something_went_wrong2)
return SOMETHING2_ERROR;
... more code goes here
if (something_went_wrong3)
return SOMETHING3_ERROR;
return 0;
}
If a function has multiple "successful" return values, I'll use if/else to select among them. If a function has a normal return value, but one or more ways that may abnormally exit early, I generally won't use an "else" for the normal path. For example, I think it's far more "natural" to say:
int do_something(int arg1)
{
if (arg1 > MAX_ARG1_VALUE)
return ARG1_ERROR;
... main guts of code here
return 0;
}
than to say:
int do_something(int arg1)
{
if (arg1 > MAX_ARG1_VALUE)
return ARG1_ERROR;
else
{
... main guts of code here
return 0;
}
}
or
int do_something(int arg1)
{
if (arg1 <= MAX_ARG1_VALUE)
{
... main guts of code here
return 0;
}
else
return ARG1_ERROR;
This distinction becomes especially significant if there are multiple things that can "go wrong", e.g.
int do_something(int arg1)
{
if (arg1 > MAX_ARG1_VALUE)
return ARG1_ERROR;
... some code goes here
if (something_went_wrong1)
return SOMETHING1_ERROR;
... more code goes here
if (something_went_wrong2)
return SOMETHING2_ERROR;
... more code goes here
if (something_went_wrong3)
return SOMETHING3_ERROR;
return 0;
}
Nested 'if/else' statements in such cases can get ugly. The most important caveat with this approach is that any cleanup code for early exits must be given explicitly, or else a wrapper function must be used to ensure cleanup.
Some would say that multiples return would be the problem here. But it's not really my point.
For my point of view, the if/else if is really important, because even if in your case you return some value, removing the elses would mean that you wouldn't put them anyway, and that would mean a totally different thing if the returns were not here.
Plus, imagine someday someone want to edit your code, and clean it up for a single return, this person could misunderstand your code and do a grave mistake like this :
对于简单的 1-liners,我倾向于省略 else,但如果有更复杂的 if 块,我倾向于更喜欢 else 来使其清晰条件是相互排斥的。
For simple 1-liners I tend to leave out the else but if there's more complex if blocks I tend to prefer the else to make it clear that the conditions are mutually exclusive.
对于一个简单的 if 语句来说,没有太多代码行且具有多个返回值是没有问题的。然而,没有什么比这更让我愤怒的了:
function doTemperatureCalculations(double temperature) {
if (temperature < 20) {
/*
Gazillion lines of code here .....
*/
return "Very cold!";
} else if (temperature < 40) {
/*
Another gazillion loc .....
*/
return "Summer in the North Pole.";
} else {
/*
Multiple returns embedded throughout ....
*/
}
}
For a simple if statement without too many lines of code having multiple returns is no problem. However, nothing infuriates me quite so much as:
function doTemperatureCalculations(double temperature) {
if (temperature < 20) {
/*
Gazillion lines of code here .....
*/
return "Very cold!";
} else if (temperature < 40) {
/*
Another gazillion loc .....
*/
return "Summer in the North Pole.";
} else {
/*
Multiple returns embedded throughout ....
*/
}
}
if (error condition) {
do some stuff;
return;
} else {
do stuff;
if (other error condition) {
do some stuff1;
return;
} else {
do some other stuff;
return
}
}
下面的代码保持了嵌套级别,从而降低了代码复杂性:
if (error condition) {
do some stuff;
return;
}
do stuff;
if (other error condition) {
do some stuff1;
return;
}
do some other stuff;
return;
在您的示例中,无论哪种方式都很简单。但在许多情况下,您最好使用查找表来处理此类事情并从文件/数据库中读取值。为了提高 C 语言的效率,通常将其编码为结构数组。
我能想到其他人的优点。如果你想添加一个新的最后一个案例,如果没有 else,你可能会忘记在当前的“太热条件”中添加一个 if ,如果你想在 120 或其他位置添加“死亡”。而使用 else 时,您知道需要将最后一个 else 放在“Dying”前面,因此您更有可能考虑将 else if 放在“Too Hot”前面。另外,如果你只是在“Dying”上加上 else,你会得到一个编译错误,迫使你思考。
In this case it is more clear. In the general case you may want to leave the elses off as they can contribute to more nesting and code complexity. For example:
if (error condition) {
do some stuff;
return;
} else {
do stuff;
if (other error condition) {
do some stuff1;
return;
} else {
do some other stuff;
return
}
}
The code below keeps the level of nesting down which reduces code complexity:
if (error condition) {
do some stuff;
return;
}
do stuff;
if (other error condition) {
do some stuff1;
return;
}
do some other stuff;
return;
In your example it is easy either way. But in many cases you would be better off using a lookup table for this sort of thing and reading the values from a file/database. For efficiency in C often this would be coded as an array of structs.
The else does add some clarity in that it makes it clear that the cases are mutually exclusive. However the idiom of returning like you do is obvious to many programmers, so either way the majority will know what you meant.
I can think of an advantage of the elses. If you want to add a new last case, without the elses you might forget to add an if to the currently "Too Hot Condition" if say you wanted to add "Dying" at 120 or something. while with the elses you know that you need the final else to be in front of "Dying" so you will be more likely to think about putting the else if in front of "Too Hot". Also if you just put an else on "Dying" you will get a compile error which forces you to think.
def temperature_message(temp)
case temp
when (-1.0/0.0)...32
'Freezing'
when 32...60
'Brr'
when 60...80
'Comfortable'
else
'Too hot'
end
end
尽管我必须承认我仍然发现第一个最容易阅读。
因为这基本上是一个映射表,所以我会尝试将其格式化,以便每个阅读代码的人立即看到“表性”:
def temperature_message(temp)
case temp
when (-1.0/0.0)...32 then 'Freezing'
when 32...60 then 'Brr'
when 60...80 then 'Comfortable'
else 'Too hot'
end
end
Personally, I think the elses are unnecessary. Since this question is tagged as [language-agnostic], I'm going to provide a couple of examples of how I would write it:
def temperature_message(temp)
return 'Freezing' if temp < 32
return 'Brr' if temp < 60
return 'Comfortable' if temp < 80
'Too hot'
end
This is typical guard clause style, which both I personally and the Ruby community in general use quite often.
def temperature_message(temp)
case
when temp < 32
'Freezing'
when temp < 60
'Brr'
when temp < 80
'Comfortable'
else
'Too hot'
end
end
This is a typical switch as you would find it in some less powerful languages. This is probably one that I would not use, I would refactor it like this:
def temperature_message(temp)
case temp
when (-1.0/0.0)...32
'Freezing'
when 32...60
'Brr'
when 60...80
'Comfortable'
else
'Too hot'
end
end
Although I must admit I still find the first one easiest to read.
Since this is basically a mapping table, I would try to format it as such, so that everybody who reads the code, immediately sees the "table-ness":
def temperature_message(temp)
case temp
when (-1.0/0.0)...32 then 'Freezing'
when 32...60 then 'Brr'
when 60...80 then 'Comfortable'
else 'Too hot'
end
end
This also applies to your original Java implementation:
The redundant elses make me cringe. The extra syntax and indentation makes it harder for me to read. I just got through removing a bunch of these from some code I inherited.
Most cases of redundant code are mistakes, so by implication a redundant 'else' looks like a mistake to me even if you put it there on purpose. The impression I get is of code that was originally written without embedded returns, then someone rewrote it to have the embedded returns, but they were too lazy to remove the elses.
A single if/return is easy to understand; so are 4 in a row. It's "that case is done; let's move on". A long chain of if/elses can be a pain to read; you need to read all the way to the bottom before you find out what happens. The saving grace is it allows a single return to be used -- a feature that is overrated IMO but I'll admit it does provide some value. However a long chain of if/elses combined with returns mixed in amongst the elses is the worst of both worlds -- all the disadvantages of multiple returns, and made to look like one large construct you have to get in your head all at once. Ugh.
From a theoretical perspective consider this: The zone between the return and the else is essentially unreachable code. Sure, it only contains whitespace, but the zone shouldn't even be there at all.
Finally, an example of if/return/else taken to its redundant conclusion. I've seen a few of these lately. Why in the world is there an else block? The code in the else block executes under the same conditions as the code directly after it:
I agree that the elses makes it more clear. The final else especially helps to make a visual distinction between the case where every branch has a return, and the cases where only some branches have a return (which could be a smell).
There's no point. You're adding needless semantic and other overheads for absolutely zero benefit. When you return, you return and control is over. Pretending anything else is superfluous and just makes you look like you don't know what the return statement does.
发布评论
评论(16)
当可以使用 SWITCH 语句时谁使用 IF/ELSE IF...?
我更喜欢单个 RETURN 语句 - 多个 return 语句会让调试变得很痛苦......
Who uses IF/ELSE IF... when you can use a SWITCH statement?
My preference is for the single RETURN statement - multiple return statements can make debugging a pain...
我不认为我首先会以这种方式编写,但是按照前提,我猜测任何编译器都会产生相同的代码,无论您选择编写哪种方法,所以没有技术原因我认为这对其中之一有利。
因此,该参数是单一或复合语句。
我认为应该使用“最少意外”规则,在这种情况下,将调用 FOR 来包含多余的 else 语句。
附言。我总是会发送一个以摄氏度为单位的温度,哎呀,刚刚破坏了你的功能!
I don't think I'd write in this way in the first place, but going along with the premise, I'm guessing that any compiler would crank out the same code whichever method you chose to write, so there is no technical reason that I can think would favour one over the other.
The argument is therefore Single or Compound statement.
I think the rule of "least surprise" should be used, which in this case would call FOR the superfluous else statements to be included.
PS. I would always send a temperature in degrees centigrade, oops, just broke your function!
很好。如果没有“else”,这条线
就没有说服力。有了“else”,显然还有其他前提条件。
it's good. without "else", this line
would be unconvincing. with "else", it's clear that there are other preconditions.
我自己更喜欢案例陈述,但这将使这是一个特定于语言的主题,而不是与语言无关的主题。
我发现这些语句比 if..else 语句更容易阅读。
I prefer case statements myself but that would make this a language specific topic and not language-agnostic topic.
I find these alot easier to read then if..else statements.
在这种特殊情况中,唯一可行的选择是使用条件运算符
?:
。留下了初学者如何阅读的问题。
参考文献
?:
相关问题
The only feasible alternative in this particular case is to grab the conditional operator
?:
.Left behind the question how that's readable to starters.
References
?:
Related questions
这取决于很多因素,例如代码的复杂程度。对于像这样的简单示例,我会将返回值与 if 放在同一行,而不使用 else。结构和行为很清晰:
当我有更复杂的代码时,我发现不使用 return 或 continue/break 突破嵌套,而是分配给状态或结果变量很有用。然后,即使该块是单个语句,我也会包含 {},主要是为了保持代码中结构表示方式的一致性,同时也稍微降低以后编辑忘记将语句更改为块的风险。
如果这个例子更复杂,我可能会这样编码:
It depends on a lot of things like how complex your code is. With a simple example like this, I'd put the returns on the same line as the ifs, and not use elses. The structure and behaviour is clear:
When I have more complex code I find it useful to not break out from the nesting with returns or continue/break, but to assign to state or result variables. I will then also include {} even if the block is a single statement, mostly to keep the consistency in how the structure is represented in code, but also to slightly reduce the risk that later edits will forget to change a statement to a block.
If this example was more complex, I'd probably code it like this:
如果一个函数有多个“成功”返回值,我将使用 if/else 在其中进行选择。如果一个函数有一个正常的返回值,但是一种或多种方式可能会异常提前退出,我通常不会使用“else”作为正常路径。 更“自然”
例如,我认为说:比说:
或
,如果有多个事情可能“出错”,那么这种区别就变得尤其重要,例如
在这种情况下嵌套的“if/else”语句可能会变得丑陋。这种方法最重要的警告是,必须明确给出早期退出的任何清理代码,否则必须使用包装函数来确保清理。
If a function has multiple "successful" return values, I'll use if/else to select among them. If a function has a normal return value, but one or more ways that may abnormally exit early, I generally won't use an "else" for the normal path. For example, I think it's far more "natural" to say:
than to say:
or
This distinction becomes especially significant if there are multiple things that can "go wrong", e.g.
Nested 'if/else' statements in such cases can get ugly. The most important caveat with this approach is that any cleanup code for early exits must be given explicitly, or else a wrapper function must be used to ensure cleanup.
有人会说,多次回报将是这里的问题。但这并不是我的重点。
就我的观点而言, if/else if 非常重要,因为即使在您的情况下您返回了一些值,删除 else 也意味着您无论如何都不会放置它们,如果退货不在这里。
另外,想象一下有一天有人想要编辑你的代码,并清理它以获得一次返回,这个人可能会误解你的代码并犯下这样的严重错误:
为了澄清我的观点,保留其他,它使您的代码保持清晰。
Some would say that multiples return would be the problem here. But it's not really my point.
For my point of view, the if/else if is really important, because even if in your case you return some value, removing the elses would mean that you wouldn't put them anyway, and that would mean a totally different thing if the returns were not here.
Plus, imagine someday someone want to edit your code, and clean it up for a single return, this person could misunderstand your code and do a grave mistake like this :
To clarify my point of view, keep the elses, it keep your code clear.
对于简单的 1-liners,我倾向于省略
else
,但如果有更复杂的if
块,我倾向于更喜欢else
来使其清晰条件是相互排斥的。For simple 1-liners I tend to leave out the
else
but if there's more complexif
blocks I tend to prefer theelse
to make it clear that the conditions are mutually exclusive.对于一个简单的
if
语句来说,没有太多代码行且具有多个返回值是没有问题的。然而,没有什么比这更让我愤怒的了:For a simple
if
statement without too many lines of code having multiple returns is no problem. However, nothing infuriates me quite so much as:在这种情况下就更清楚了。在一般情况下,您可能希望忽略 else,因为它们会导致更多嵌套和代码复杂性。例如:
下面的代码保持了嵌套级别,从而降低了代码复杂性:
在您的示例中,无论哪种方式都很简单。但在许多情况下,您最好使用查找表来处理此类事情并从文件/数据库中读取值。为了提高 C 语言的效率,通常将其编码为结构数组。
else 确实增加了一些清晰度,因为它清楚地表明这些情况是相互排斥的。然而,像你一样返回的习惯用法对许多程序员来说是显而易见的,所以无论哪种方式,大多数人都会明白你的意思。
我能想到其他人的优点。如果你想添加一个新的最后一个案例,如果没有 else,你可能会忘记在当前的“太热条件”中添加一个 if ,如果你想在 120 或其他位置添加“死亡”。而使用 else 时,您知道需要将最后一个 else 放在“Dying”前面,因此您更有可能考虑将 else if 放在“Too Hot”前面。另外,如果你只是在“Dying”上加上 else,你会得到一个编译错误,迫使你思考。
In this case it is more clear. In the general case you may want to leave the elses off as they can contribute to more nesting and code complexity. For example:
The code below keeps the level of nesting down which reduces code complexity:
In your example it is easy either way. But in many cases you would be better off using a lookup table for this sort of thing and reading the values from a file/database. For efficiency in C often this would be coded as an array of structs.
The else does add some clarity in that it makes it clear that the cases are mutually exclusive. However the idiom of returning like you do is obvious to many programmers, so either way the majority will know what you meant.
I can think of an advantage of the elses. If you want to add a new last case, without the elses you might forget to add an if to the currently "Too Hot Condition" if say you wanted to add "Dying" at 120 or something. while with the elses you know that you need the final else to be in front of "Dying" so you will be more likely to think about putting the else if in front of "Too Hot". Also if you just put an else on "Dying" you will get a compile error which forces you to think.
就我个人而言,我认为
else
是不必要的。由于这个问题被标记为[与语言无关]
,我将提供几个示例来说明如何编写它:这是典型的保护子句风格,我个人和 Ruby 都采用这种风格一般社区经常使用。
这是一个典型的
switch
,您会在一些功能较弱的语言中找到它。这可能是我不会使用的一个,我会像这样重构它:尽管我必须承认我仍然发现第一个最容易阅读。
因为这基本上是一个映射表,所以我会尝试将其格式化,以便每个阅读代码的人立即看到“表性”:
这也适用于您最初的 Java 实现:
当然,因为它 基本上是一个映射表,您也可以将其实现为映射:
Personally, I think the
else
s are unnecessary. Since this question is tagged as[language-agnostic]
, I'm going to provide a couple of examples of how I would write it:This is typical guard clause style, which both I personally and the Ruby community in general use quite often.
This is a typical
switch
as you would find it in some less powerful languages. This is probably one that I would not use, I would refactor it like this:Although I must admit I still find the first one easiest to read.
Since this is basically a mapping table, I would try to format it as such, so that everybody who reads the code, immediately sees the "table-ness":
This also applies to your original Java implementation:
Of course, since it is basically a mapping table, you might just as well implement it as a map:
多余的其他让我感到畏缩。额外的语法和缩进使我更难阅读。我刚刚从我继承的一些代码中删除了其中的一些内容。
大多数冗余代码都是错误,因此暗示冗余的“else”对我来说看起来像是一个错误,即使你是故意把它放在那里的。我得到的印象是,最初编写的代码没有嵌入返回值,然后有人重写了它以具有嵌入返回值,但他们懒得删除其他内容。
单个 if/return 很容易理解;连续 4 个也是如此。这是“案子已经完成;让我们继续前进”。长长的 if/else 链读起来很痛苦;在你知道发生了什么之前,你需要从头到尾读完。可取之处在于它允许使用单一回报——这一功能在我看来被高估了,但我承认它确实提供了一些价值。然而,一长串 if/else 与混合在 else 中的 return 相结合是两全其美的情况 - 多重返回的所有缺点,并且看起来像是一个必须同时进入头脑的大型结构。啊。
从理论角度考虑:return 和 else 之间的区域本质上是无法访问的代码。当然,它只包含空格,但该区域根本不应该存在。
最后,通过一个 if/return/else 的例子得出了多余的结论。我最近看到了其中一些。世界上为什么会有 else 块? else 块中的代码与紧随其后的代码在相同的条件下执行:
The redundant elses make me cringe. The extra syntax and indentation makes it harder for me to read. I just got through removing a bunch of these from some code I inherited.
Most cases of redundant code are mistakes, so by implication a redundant 'else' looks like a mistake to me even if you put it there on purpose. The impression I get is of code that was originally written without embedded returns, then someone rewrote it to have the embedded returns, but they were too lazy to remove the elses.
A single if/return is easy to understand; so are 4 in a row. It's "that case is done; let's move on". A long chain of if/elses can be a pain to read; you need to read all the way to the bottom before you find out what happens. The saving grace is it allows a single return to be used -- a feature that is overrated IMO but I'll admit it does provide some value. However a long chain of if/elses combined with returns mixed in amongst the elses is the worst of both worlds -- all the disadvantages of multiple returns, and made to look like one large construct you have to get in your head all at once. Ugh.
From a theoretical perspective consider this: The zone between the return and the else is essentially unreachable code. Sure, it only contains whitespace, but the zone shouldn't even be there at all.
Finally, an example of if/return/else taken to its redundant conclusion. I've seen a few of these lately. Why in the world is there an else block? The code in the else block executes under the same conditions as the code directly after it:
我同意 else 更清楚了。最后的 else 特别有助于在每个分支都有返回的情况和只有某些分支有返回的情况(这可能是一种气味)之间进行视觉区分。
I agree that the elses makes it more clear. The final else especially helps to make a visual distinction between the case where every branch has a return, and the cases where only some branches have a return (which could be a smell).
没有意义。您添加了不必要的语义和其他开销,而收益绝对为零。当你回来时,你就回来了,控制就结束了。假装其他任何东西都是多余的,只会让你看起来不知道 return 语句的作用。
There's no point. You're adding needless semantic and other overheads for absolutely zero benefit. When you return, you return and control is over. Pretending anything else is superfluous and just makes you look like you don't know what the return statement does.