누군가가 여전히 C #에서 "goto"키워드 구문을 사용하는지 여부와 그 이유가 무엇인지 궁금합니다.
나는 독자가 코드를 훑어 보도록 만드는 어떤 진술을 나쁜 습관으로 보는 경향이 있지만 그러한 구문을 사용하는 데 신뢰할 수있는 시나리오가 있는지 궁금합니다.
goto
루프를 끊고 특정 조건에 따라 시작 문으로 돌아가는 데 사용합니다
누군가가 여전히 C #에서 "goto"키워드 구문을 사용하는지 여부와 그 이유가 무엇인지 궁금합니다.
나는 독자가 코드를 훑어 보도록 만드는 어떤 진술을 나쁜 습관으로 보는 경향이 있지만 그러한 구문을 사용하는 데 신뢰할 수있는 시나리오가 있는지 궁금합니다.
goto
루프를 끊고 특정 조건에 따라 시작 문으로 돌아가는 데 사용합니다
답변:
goto가 실제로 가독성을 향상시킬 수있는 (드문) 경우가 있습니다. 실제로 링크 한 문서에는 두 가지 예가 나열되어 있습니다.
goto의 일반적인 용도는 제어를 특정 switch-case 레이블 또는 switch 문의 기본 레이블로 전송하는 것입니다.
goto 문은 깊이 중첩 된 루프를 벗어나는데도 유용합니다.
다음은 후자의 예입니다.
for (...) {
for (...) {
...
if (something)
goto end_of_loop;
}
}
end_of_loop:
물론 코드를 함수로 리팩토링하거나 주변에 더미 블록을 사용하는 등이 문제를 해결하는 다른 방법도 있습니다 (자세한 내용은 이 질문 참조). 참고로 Java 언어 디자이너는 goto를 완전히 금지 하고 대신 레이블이 지정된 break 문을 도입 하기로 결정했습니다 .
이 부분이 기억 나
switch (a)
{
case 3:
b = 7;
// We want to drop through into case 4, but C# doesn't let us
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
이와 같은 것에
switch (a)
{
case 3:
b = 7;
goto case 4;
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
이것을 참조하십시오
C # 5에서 비동기 메서드를 사용할 때 컴파일러가 생성하는 코드의 종류를 보여주기 위해 Eduasync 에서 광범위하게 사용합니다 . 반복자 블록에서도 동일한 것을 볼 수 있습니다.
"일반"코드에서는 마지막으로 사용한 시간이 기억 나지 않습니다.
goto는 break가 잘 작동하지 않는 많은 루프 (예 : 오류 조건)에서 벗어나는 데 적합하며 Kragen이 말했듯이 goto는 컴파일러에서 switch 문 및 기타 사항을 생성하는 데 사용됩니다.
를 사용한 기억이 없습니다 goto
. 그러나 어쩌면 그것은 당신이 정말로 (NO 종료하려면 결코 영원히 루프의 의도를 향상 break
,하지만 여전히 수 return
또는 throw
) :
forever: {
// ...
goto forever;
}
다시 말하지만 간단한 while (true)
것으로 충분합니다 ...
또한 루프의 중간에서 루프의 첫 번째 반복을 시작하려는 상황에서 사용할 수 있습니다 . 여기 에서 예제를보십시오.
goto
..하고 while(true) {..}
.. 재미있는 사용하지 않습니다
컴파일러는 goto
생성 된 반복기 블록 유형 ( yield return
키워드를 사용할 때 생성됨)과 같이 생성 된 다양한 코드 조각에서 명령문을 사용합니다 . 생성 된 XML 직렬화 유형도 goto
어딘가에 몇 개의 명령문을 가지고 있다고 확신합니다 .
C # 컴파일러가이를 처리하는 이유 / 방법에 대한 자세한 내용 은 반복자 블록 구현 세부 정보 : 자동 생성 상태 머신 을 참조하세요.
생성 된 코드 외에는 goto
일반 코드에서 명령문 을 사용할 이유가 없습니다. 코드를 이해하기 어렵게 만들고 결과적으로 오류가 발생하기 쉽습니다. 반면에goto
같이 생성 된 코드에서 명령문을 하면 생성 프로세스를 단순화 할 수 있으며 생성 된 코드를 아무도 읽거나 수정할 수없고 기계가 쓰기를 수행하기 때문에 실수 할 가능성이 없기 때문에 일반적으로 괜찮습니다.
고전적인 프로그래밍 역사의 일부뿐만 아니라 반대 주장에 유해한 것으로 간주되는 Go-to 문을 참조하십시오 goto
.
goto
하지 않습니다. 고려해야 할 것.
프로세서는 적어도 하나의 점프 명령을 구현하고 많은 명령문이 구현 또는 해석에 사용한다고 확신합니다.
3 세대 또는 4 세대 언어를 사용할 때 좋은 점 중 하나는 이러한 물리적 세부 사항이 우리에게서 추상화된다는 것입니다. 우리는 유출 추상화 의 법칙을 염두에 두어야 하지만 의도 한대로 도구를 사용해야한다고 생각합니다 ( 죄송합니다 ). 내가 코드를 작성하고 있고 goto
좋은 생각처럼 보인다면 리팩토링해야 할 때입니다. 구조화 된 언어의 목적은 이러한 "점프"를 피하고 엔지니어링에서 논리적 흐름을 만드는 것입니다.
나는 사용을 피해야 break
하지만 성능상의 이점을 간과 할 수 없습니다. 그러나 상호 적으로 필요한 중첩 루프가있는 경우 break
리팩토링 해야합니다 .
누군가 goto
리팩토링보다 더 나은 사용을 제안 할 수 있다면 기꺼이 내 대답을 철회 할 것입니다.
나는 내가 여기 " 자전거 창고 " 로 서두르지 않기를 바랍니다 . Kragen이 말했듯이 Dijkstra 에게 충분한 것은 나에게 충분합니다.
dynamic
객체를 내가 필요로하는 값으로 내려 여러 사전을 포함하고 그것의 객체 그래프를 산책. 매개 변수가 dynamic
있지만 정확한 개체 모양을 기대하는 메서드를 사용하는 것은 의미가 없습니다 . goto를 사용하여 여러 레이어를 분리하고 이러한 개체 컬렉션을 계속 진행합니다. [더 나은 액세스를 제공 할 수 있도록 나는 반사 또는 동적 그래서 그것이, 종류를 보유하고 있지 않습니다]
Goto는 결코 더 좋지 않습니다. 그리고 계속, 브레이크 (스위치 / 케이스 제외), (다중) 리턴, 던지기도 최소한으로 유지해야합니다. 네스트 루프의 중간에서 벗어나고 싶지 않습니다. 항상 루프 제어 명령문에 모든 루프 제어가 있어야합니다. 들여 쓰기에는 정보가 있으며 이러한 모든 명령문은 해당 정보를 버립니다. 모든 들여 쓰기를 제거하는 것이 좋습니다.