Switch Statement Fallthrough… 허용되어야합니까? [닫은]
내가 기억할 수있는 한 나는 switch 문 폴 스루 사용을 피했다. 사실, 나는 그것이 스위치 문장의 버그에 지나지 않는다는 것을 일찍 내 머리에 뚫었 기 때문에 가능한 일을 할 수있는 방법으로 내 의식에 들어가는 것을 기억할 수 없습니다. 그러나 오늘 나는 그것을 디자인에 의해 사용하는 일부 코드를 만났고, 이것은 커뮤니티의 모든 사람들이 switch 문 폴 스루에 대해 어떻게 생각하는지 즉시 궁금해했습니다.
프로그래밍 언어가 명시 적으로 허용해서는 안되는 것입니까 (해결책을 제공하지만 C #처럼) 아니면 프로그래머의 손에 맡길 수있을만큼 강력한 언어의 기능입니까?
편집 : 나는 폴스 루가 의미하는 바에 대해 충분히 구체적이지 않았습니다. 이 유형을 많이 사용합니다.
switch(m_loadAnimSubCt){
case 0:
case 1:
// Do something
break;
case 2:
case 3:
case 4:
// Do something
break;
}
그러나 나는 이와 같은 것에 대해 걱정합니다.
switch(m_loadAnimSubCt){
case 0:
case 1:
// Do something but fall through to the other cases
// after doing it.
case 2:
case 3:
case 4:
// Do something else.
break;
}
이렇게하면 case가 0, 1 일 때마다 switch 문에서 모든 작업을 수행합니다. 나는 이것을 의도적으로 보았고 switch 문을 이런 방식으로 사용해야한다는 데 동의하는지 모르겠습니다. 첫 번째 코드 예제는 매우 유용하고 안전하다고 생각합니다. 두 번째는 위험 해 보입니다.
그것은 당신이 폴 스루라고 생각하는 것에 달려 있습니다. 나는 이런 종류의 일로 괜찮습니다.
switch (value)
{
case 0:
result = ZERO_DIGIT;
break;
case 1:
case 3:
case 5:
case 7:
case 9:
result = ODD_DIGIT;
break;
case 2:
case 4:
case 6:
case 8:
result = EVEN_DIGIT;
break;
}
그러나 케이스 라벨 뒤에 다른 케이스 라벨로 넘어가는 코드가 있다면, 저는 거의 항상 그 악한 것으로 간주 할 것입니다. 아마도 공통 코드를 함수로 옮기고 두 곳에서 호출하는 것이 더 좋은 생각 일 것입니다.
양날의 검입니다. 때로는 매우 유용하고 종종 위험합니다.
When is it good? When you want 10 cases all processed the same way...
switch (c) {
case 1:
case 2:
... do some of the work ...
/* FALLTHROUGH */
case 17:
... do something ...
break;
case 5:
case 43:
... do something else ...
break;
}
The one rule I like is that if you ever do anything fancy where you exclude the break, you need a clear comment /* FALLTHROUGH */ to indicate that was your intention.
Fallthrough is really a handy thing, depending on what you're doing. Consider this neat and understandable way to arrange options:
switch ($someoption) {
case 'a':
case 'b':
case 'c':
// do something
break;
case 'd':
case 'e':
// do something else
break;
}
Imagine doing this with if/else. It would be a mess.
Have you heard of Duff's device? This is a great example of using switch fallthrough.
It's a feature that can be used and it can be abused, like almost all language features.
It can be very useful a few times, but in general, no-fallthrough is the desired behavior. Fallthrough should be allowed, but not implicit.
An example, to update old versions of some data:
switch (version) {
case 1:
// update some stuff
case 2:
// update more stuff
case 3:
// update even more stuff
case 4:
// and so on
}
I'd love a different syntax for fallbacks in switches, something like, errr..
switch(myParam)
{
case 0 or 1 or 2:
// do something;
break;
case 3 or 4:
// do something else;
break;
}
Note: This would already be possible with enums, if you declare all cases on your enum using flags right? Doesn't sound so bad either, the cases could (should?) very well be part of your enum already.
Maybe this would be a nice case (no pun intended) for a fluent interface using extension methods? Something like, errr...
int value = 10;
value.Switch()
.Case(() => { /* do something; */ }, new {0, 1, 2})
.Case(() => { /* do something else */ } new {3, 4})
.Default(() => { /* do the default case; */ });
Although that's probably even less readable :P
As with anything: if used with care, it can be an elegant tool.
However, i think the drawbacks more than justify NOT to use it, and finally not to allow it anymore (C#). Among the problems are:
- it's easy to "forget" a break
- it's not always obvious for code maintainers THAT an omitted break was intentional
good use of a switch/case fallthrough:
switch (x)
{
case 1:
case 2:
case 3:
do something
break;
}
BAAAAAD use of a switch/case fallthrough:
switch (x)
{
case 1:
some code
case 2:
some more code
case 3:
even more code
break;
}
This can be rewritten using if/else constructs with no loss at all in my opinion.
My final word: stay away from fall-through case labels as in the BAD example, unless you are maintaining legacy code where this style is used and well understood.
Powerful and dangerous. The biggest problem with fall-through is that it's not explicit. For example, if you come across frequently-edited code that has a switch with fall-throughs, how do you know that's intentional and not a bug?
Anywhere I use it, I ensure that it's properly commented:
switch($var) {
case 'first':
// fall-through
case 'second':
i++;
break;
}
Using fall-through like in your first example is clearly OK, I would not consider it a real fall-through.
The second example is dangerous and (if not commented extensively) non-obvious. I teach my students not to use such constructs UNLESS they consider it worth the to devote a comment block to it, which describes that this is an intentional fallthrough, and why this solution is better than the alternatives. This discourages sloppy use, but still makes it allowed in the cases where it is used to an advantage.
This is more or less equivalent to what we did in space projects when someone wanted to violate the coding standard: they had to apply for dispensation (and I was called on to advise about the ruling).
I don't like my switch
statements to fall through - it's far too error prone and hard to read. The only exception is when multiple case
statements all do exactly the same thing.
If there is some common code that multiple branches of a switch statement want to use, I extract that into a separate common function that can be called in any branch.
In some instances, using fall-throughs is an act of laziness on the part of the programmer - they could use a series of || statements, for example, but instead use a series of 'catch-all' switch cases.
That being said, I've found them to be especially helpful when I know that eventually I'm going to need the options anyway (for example in a menu response), but have not yet implemented all the choices. Likewise, if you're doing a fall-through for both 'a' and 'A', I find it substantially cleaner to use the switch fall-through than a compound if statement.
It's probably a matter of style and how the programmers think, but I'm not generally fond of removing components of a language in the name of 'safety' - which is why I tend towards C and its variants/descendants more than, say, Java. I like being able to monkey-around with pointers and the like, even when I have no "reason" to.
fall thought should be used only when it is used as a jump table into a block of code. If there is any part of the code with an unconditional break before more cases, all the case groups should end that way. Anything else is "evil".
참고URL : https://stackoverflow.com/questions/188461/switch-statement-fallthrough-should-it-be-allowed
'program story' 카테고리의 다른 글
C ++ 맵에서 키 반복 (0) | 2020.08.08 |
---|---|
확장 구성을 편집 한 후 VScode를 다시 시작하는 방법은 무엇입니까? (0) | 2020.08.07 |
메소드 서명의 Java "매개 변수"? (0) | 2020.08.07 |
RegEx-가변 길이의 숫자 일치 (0) | 2020.08.07 |
문자열에 대한 해시 함수 (0) | 2020.08.07 |