"if x then return"뒤에 "else"가 거의 사용되지 않는 이유는 무엇입니까?
이 방법:
boolean containsSmiley(String s) {
if (s == null) {
return false;
}
else {
return s.contains(":)");
}
}
동등하게 작성할 수 있습니다.
boolean containsSmiley(String s) {
if (s == null) {
return false;
}
return s.contains(":)");
}
내 경험상 두 번째 형태는 특히 더 복잡한 방법 (이러한 출구 지점이 여러 개있을 수 있음)에서 더 자주 보이며 "던지기"와 "반환"에 대해서도 마찬가지입니다. 그러나 첫 번째 형식은 코드의 조건부 구조를 더 명확하게 만듭니다. 하나를 선호하는 이유가 있습니까?
(관련 : 함수에 return 문이 하나만 있어야합니까? )
내 경험상 코드에 따라 다릅니다. 내가 무언가에 대해 '보호'한다면 다음과 같이 할 것입니다.
if (inputVar.isBad()) {
return;
}
doThings();
요점은 분명합니다. 그 진술이 거짓이면 함수가 계속되는 것을 원하지 않습니다.
반면에 여러 옵션이있는 일부 함수가 있으며이 경우 다음과 같이 작성합니다.
if (inputVar == thingOne) {
doFirstThing();
} else if (inputVar == secondThing) {
doSecondThing();
} else {
doThirdThing();
}
다음과 같이 쓸 수 있지만 :
if (inputVar == thingOne) {
doFirstThing();
return;
}
if (inputVar == thingTwo) {
doSecondThing();
return;
}
doThingThree();
return;
실제로 코드가 수행하는 작업을 가장 명확하게 보여주는 방법이 결정됩니다 (반드시 코드의 어느 비트가 가장 짧거나 들여 쓰기가 가장 적은 것은 아님).
이 else
경우는 중복 될뿐만 아니라 함수의 기본 코드에 대해 불필요한 추가 들여 쓰기를 만듭니다.
이것은 Guard Clause 라는 패턴 입니다. 아이디어는 모든 검사를 미리 수행하여 중첩 된 조건을 줄여 가독성을 높이는 것입니다.
링크에서 :
double getPayAmount() {
double result;
if (_isDead) {
result = deadAmount();
} else {
if (_isSeparated) {
result = separatedAmount();
} else {
if (_isRetired) {
result = retiredAmount();
} else {
result = normalPayAmount();
}
}
}
return result;
}
Guard Clause를 사용하면 다음 결과를 볼 수 있습니다.
double getPayAmount() {
if (_isDead) return deadAmount();
if (_isSeparated) return separatedAmount();
if (_isRetired) return retiredAmount();
return normalPayAmount();
};
이 모든 것을 볼 수 있습니다.
if (condition) {
return var;
}
// by nature, when execution reaches this point, condition can only be false,
// therefore, the else is unnecessary
return other_var;
대부분의 경우 else 절을 추가하는 것은이 경우 불필요 할뿐만 아니라 많은 경우 컴파일러에 의해 최적화됩니다 .
컴퓨터가이 코드를 어떻게 생각하는지 생각해보십시오 (머신 코드 측면에서 데모 용으로 여기에서 의사 코드로 단순화).
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
코드 (다시 말하지만 이것은 어셈블리가 아니라 의사 코드입니다)는 if/then/else
조건부 와 똑같은 방식으로 작동합니다 .
프로그래머가 자신의 코드를 통해 가능한 모든 경로를 생각해야하기 때문에 함수에 대해 여러 개의 가능한 종료 지점을 갖는 것은 많은 사람들에 의해 나쁘거나 혼란스러운 관행으로 간주됩니다. 또 다른 방법은 다음과 같습니다.
return (condition) ? var : other_var;
이는 코드를 단순화하고 새로운 종료점을 생성하지 않습니다.
다음과 같이 작성하는 것을 선호합니다.
boolean containsSmiley(String s) {
return s != null && s.contains(":)");
}
코딩 스타일에 대한 "토론"과 마찬가지로 정답은 없습니다. 다음 고려 사항을 적용하는 것을 선호합니다.
코드가 모든 상황에서 예상대로 작동합니까? (최소한의 놀라움의 원칙)
다음 개발자 (나 자신 또는 다른 사람)가 작업 내용과 이유를 이해할 수 있습니까?
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.
Once I'm happy that I have satisfied the above, the rest generally just falls falls into line.
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?
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.
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.
It's religious argument and at the end of the day it doesn't matter. I'd even argue that the first form is more readable in some circumstances. If you have large chunks of code in an if-elseif-elseif-else
, it's easier, at first glance to see what the default return is.
if (s == null) {
return false;
}
else if (s.Contains(":))")) {
return true;
}
else if (s.Contains(":-(")) {
return false;
}
return s.contains(":)");
Occam's Razor is the principle that "entities must not be multiplied beyond necessity."
The if
statement is checking/enforcing your contract/expectation of not receiving null values. For that reason, I would prefer to see it separated from the rest of the function as it doesn't have anything to do with the actual logic of what you're trying to accomplish (though this case is very simple).
In most cases, though, I prefer code to be as explicit as possible in its intent. If there's something that you can restructure about your function to make it more readable for others, do it. As a professional programmer, your goal should really be to program for those who have to maintain your code after you (including yourself 2 years later...). Anything you can do to help them out is worth doing.
The else
is 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.
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.
The first form is simply less verbose - when you return a value you automatically leave the scope of the function you're in and return to the caller, so any of the code thereafter will only execute if the IF statement doesn't evaluate to true and subsequently return anything.
I'd argue for readability. If you're scanning screens of code trying to figure out what the code does, it's a visual prompt to the developer.
...but it's not really needed because we all comment our code so well, right? :)
In my opinion, the second one makes more sense. It serves as more of a 'default' action, like a switch. If it doesn't match any of the other exit points, then do that. You don't really need an else there. I would say if the entire function is only if and elseif, then an else would make sense there because it's one giant conditional. If there's multiple conditionals and other functions that are run within it, then a default return at the end would be used.
While having an else is correct and there's nothing wrong with it in terms of logic and runnability, I like to avoid the initial WTF moment when the function has no return statement outside of the if/else scope.
As you can see, different people have different opinions on readability. Some people think that fewer lines of code tends to make the code more readable. Others think that the symmetry of the second form makes it more readable.
My take is that probably, both views are correct ... for the people who hold them. And the corollary is that you cannot write code that everyone finds optimally readable. So, the best advice is to follow what your mandated coding standard says to do (if it says anything on this) and generally use your common sense. (If you are burdened with some vociferous nitwit that insists that his way is "right" ... just go with the flow.)
Because there is an optional (switched off by default) warning in eclipse if else is used in such situation ;).
Well, some of the reason is just convention, but there is one advantage to the form above...
It's typical when coding a return statement, to make the last statement your default return value. This primarily aids during refactoring - else clauses tend to get wrapped up in other structures, or might accidentally be moved deeper into the tree.
I would prefer one exit point over multiple from maintenance perspective. Final result can be modified(or decorated) at one exit point rather than n exit points.
The second form if simpler/shorter. This doesn't always mean clearer. I suggest you do what you find clearest.. Personally I would write.
static boolean containsSmiley(String s) {
return s != null && s.contains(":)");
}
Because it's the same as writing one of the following which brings the evidence about the intention of the programmer:
boolean containsSmiley(String s) {
if (s == null) // The curly braces are not even necessary as the if contains only one instruction.
return false;
return s.contains(":)");
}
Or even this:
boolean constainsSMiley(String s) {
return string.IsNullOrEmpty(s) ? false : s.Contains(":)");
}
These two forms are:
- More elegant;
- Easier to read;
- Leaner and swifter for the reading programmer.
참고URL : https://stackoverflow.com/questions/3261849/why-is-else-rarely-used-after-if-x-then-return
'Programing' 카테고리의 다른 글
내부 결합 세 테이블 (0) | 2020.12.07 |
---|---|
$ .post와 $ .ajax의 차이점은 무엇입니까? (0) | 2020.12.07 |
Python에서 파일 크기를 변환하는 더 나은 방법 (0) | 2020.12.06 |
작업 공급자를 작업 공급자를 공유하도록 캐스팅 할 수 없습니다. (0) | 2020.12.06 |
배열의 모든 요소를 동일한 숫자로 초기화 (0) | 2020.12.06 |