내가 기억할 수있는 한 나는 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;
}
그러나 케이스 라벨 뒤에 다른 케이스 라벨로 넘어가는 코드가 있다면, 저는 거의 항상 그 악한 것으로 간주합니다. 아마도 공통 코드를 함수로 옮기고 두 곳에서 호출하는 것이 더 좋은 생각 일 것입니다.
답변
양날의 검입니다. 때로는 매우 유용하지만 종종 위험합니다.
언제 좋은가요? 10 개의 케이스를 모두 동일한 방식으로 처리하려면 …
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;
}
내가 좋아하는 한 가지 규칙은 휴식을 제외하고 멋진 일을 한 적이 있다면 / * FALLTHROUGH * /라는 명확한 주석이 필요하다는 것입니다.
답변
답변
폴 스루는 당신이하는 일에 따라 정말 편리한 일입니다. 옵션을 정렬하는 깔끔하고 이해하기 쉬운 방법을 고려하십시오.
switch ($someoption) {
case 'a':
case 'b':
case 'c':
// Do something
break;
case 'd':
case 'e':
// Do something else
break;
}
if / else로 이것을한다고 상상해보십시오. 엉망이 될 것입니다.
답변
몇 번은 매우 유용 할 수 있지만 일반적으로 폴 스루는 원하는 동작이 아닙니다. 폴 스루는 허용되어야하지만 암시 적이 어서는 안됩니다.
예를 들어 일부 데이터의 이전 버전을 업데이트하려면 다음을 수행하십시오.
switch (version) {
case 1:
// Update some stuff
case 2:
// Update more stuff
case 3:
// Update even more stuff
case 4:
// And so on
}
답변
스위치의 폴백에 대해 다른 구문을 원합니다.
switch(myParam)
{
case 0 or 1 or 2:
// Do something;
break;
case 3 or 4:
// Do something else;
break;
}
참고 : 플래그를 사용하여 열거 형의 모든 케이스를 선언하면 열거 형으로 이미 가능할 것입니다. 그렇게 나쁘게 들리지는 않습니다. 케이스는 이미 열거 형의 일부가 될 수 있습니다.
아마도 이것은 확장 메서드를 사용하는 유창한 인터페이스에 대한 좋은 사례 (말장난이 아님)일까요? 뭐, 음 …
int value = 10;
value.Switch()
.Case(() => { /* Do something; */ }, new {0, 1, 2})
.Case(() => { /* Do something else */ } new {3, 4})
.Default(() => { /* Do the default case; */ });
가독성이 떨어질 수 있지만 : P
답변
다른 것과 마찬가지로 조심스럽게 사용하면 우아한 도구가 될 수 있습니다.
그러나 단점 은 사용 하지 않는 것을 정당화 하고 마침내 더 이상 허용하지 않는 것 이상이라고 생각합니다 (C #). 문제는 다음과 같습니다.
- 휴식을 “잊기”쉽습니다.
- 생략 된 중단이 의도적 이라는 것이 코드 관리자 에게 항상 분명한 것은 아닙니다.
스위치 / 케이스 폴 스루 사용 :
switch (x)
{
case 1:
case 2:
case 3:
Do something
break;
}
스위치 / 케이스 폴 스루 사용 :
switch (x)
{
case 1:
Some code
case 2:
Some more code
case 3:
Even more code
break;
}
이것은 내 의견으로는 전혀 손실없이 if / else 구문을 사용하여 다시 작성할 수 있습니다.
내 마지막 단어 : 이 스타일이 사용되고 잘 이해되는 레거시 코드를 유지하지 않는 한 , 나쁜 예 에서와 같이 폴 스루 케이스 레이블을 멀리하십시오 .