변수가 사용되는 곳 가까이에 변수를 선언하는 이유는 무엇입니까?


10

나는 들었다 사람들이 말하는 변수는 가능한 한 자신의 사용 가까이로 선언되어야한다. 나는 이것을 이해하지 못한다.

예를 들어,이 정책은 이렇게해야한다고 제안합니다.

foreach (var item in veryLongList) {
  int whereShouldIBeDeclared = item.Id;
  //...
}

그러나 이것은 반드시 새 int반복마다 오버 헤드 가 발생 한다는 것을 의미합니다 . 사용하는 것이 낫지 않습니까?

int whereShouldIBeDeclared;
foreach (var item in veryLongList) {
  whereShouldIBeDeclared = item.Id;
  //...
}

누군가 설명해 주시겠습니까?


3
이 두 경우를 다르게 취급 한 것은 꽤 나쁜 언어 일 것입니다.
Paul Tomblin

5
당신은 잘못된 전제에서 출발합니다. 이 질문에 대한 내 답변을 참조하십시오 : stackoverflow.com/questions/6919655/…
CesarGon

8
그렇게 생각하면 일반적으로 성능 영향을 최적화하거나 고려하기에 적합하지 않습니다. 언어 구현은 현명하며, 그렇지 않다고 생각되면 편견없는 현실적인 벤치 마크를 통해 얻은 하드 데이터로이를 입증하십시오.

4
두 코드 예제에서 의미 상 큰 차이가있는 경우 서로 다른 작업을 수행합니다. 하고 싶은 일을하는 것을 사용해야합니다. 변수를 선언하는 위치에 대한 규칙은 의미 상 차이가없는 경우에만 적용됩니다.
David Schwartz

4
스케일의 반대쪽 끝을 고려하십시오-모든 것이 전역 변수입니다. 이 스펙트럼의 더 나은 끝은 확실히 '근접 사용 선언'입니까?
JBR 윌킨슨

답변:


27

이것은 많은 스타일 중에서 하나의 스타일 규칙이며, 고려할 수있는 모든 가능한 규칙 중 가장 중요한 규칙은 아닙니다. 귀하의 예제에는 int가 포함되어 있기 때문에 강력하지는 않지만 루프 내부에 고가의 객체가있을 수 있으며 루프 외부에 객체를 구성하는 데 좋은 인수가 될 수 있습니다. 그러나 이것이 처음부터이 규칙에 대한 좋은 주장이되지는 않습니다. 적용 할 수있는 다른 많은 장소가 있습니다. 루프에 고가의 객체를 구성하지 않는 것이 좋습니다. C #, 그래서 당신은 좋은 옵티 마이저를 가지고) 루프에서 초기화를 들어 올릴 수 있습니다.

이 규칙의 실제 이유는 규칙이 왜 그런지 알 수없는 이유이기도합니다. 사람들은 수백 줄, 심지어 수천 줄에 달하는 함수를 작성했으며 Visual Studio가 제공하지 않는 일반 텍스트 편집기 (메모장 생각)로 작성했습니다. 그 환경에서, 사용 된 곳에서 수백 줄 떨어진 곳에 변수를 선언하면

if (flag) limit += factor;

깃발, 한계 및 요인이 무엇인지에 대한 단서가 많지 않았습니다. 이를 위해 헝가리 표기법과 같은 명명 규칙이 채택되었으며, 사용 장소에 가까운 것을 선언하는 것과 같은 규칙이 적용되었습니다. 물론 요즘에는 리팩토링이 중요하며 함수는 일반적으로 페이지 길이보다 짧아서 선언되는 위치와 사용되는 위치 사이의 거리가 매우 멀어집니다. 당신은 0-20의 범위에서 운영하고 있으며이 특별한 경우 7은 괜찮을 것입니다. 규칙을 만든 사람은 7 줄을 없애고 700에서 누군가와 이야기하려고했습니다. 무엇보다도 Visual Studio에서는 모든 항목 위로 마우스를 가져 가서 유형을 볼 수 있으며 멤버 변수 등입니다. 그것은 그것을 선언하는 줄을 볼 필요성이 줄어든다는 것을 의미합니다.

그것은 여전히 ​​합리적으로 좋은 규칙이며, 요즘 실제로 어려워하기 어려운 규칙이며 느린 코드를 작성하는 이유로 아무도 옹호하지 않은 규칙입니다. 무엇보다도 현명해야합니다.


답변 주셔서 감사합니다. 그러나 데이터 유형에 관계없이 모든 반복마다 새로운 인스턴스가 생성됩니다. 두 번째 경우에는 매번 새로운 메모리 참조를 요구하지 않습니다. 아니면 요점을 놓쳤습니까? 그리고 C # 최적화 프로그램은 어쨌든 컴파일 할 때 자동으로 내 코드를 향상시킬 것이라고 말하고 있습니까? 나는 그것을 몰랐다!
James

2
int를 생성하는 오버 헤드는 작습니다. 복잡한 것을 구성하는 경우 오버 헤드가 더 커집니다.
Kate Gregory

17
유형과 유형을 볼 수 있다는 문제 일뿐입니다. 또한 일생의 문제이기도합니다. 변수 "wibble"이 처음 사용되기 전에 30 행으로 선언 된 경우, "wibble"을 잘못 사용하면 버그가 발생할 수있는 30 행이 있습니다. 사용되기 직전에 선언 된 경우, 이전 30 행에서 "흔들기"를 사용하면 버그가 발생하지 않습니다. 대신 컴파일러 오류가 발생합니다.
Mike Sherrill 'Cat Recall'10

이 경우 새로운 루프가 모든 루프를 생성 하지는 않습니다 . 하나의 최상위 변수가 만들어지고 모든 반복에 사용됩니다 (IL 참조). 그러나 그것은 구현 세부 사항입니다.
thecoop

"Visual Studio에서는 무엇이든 위로 마우스를 가져 가서 볼 수 있습니다"등이 있습니다. 정의로 이동하는 F12데 필요한 바로 가기가있는 정의로 이동도 있습니다 .
StuperUser

15

루프 내에서 변수를 정의하면 해당 루프에만 로컬로 표시됩니다. 독자에게는 적어도 3 가지 장점이 있습니다.

  1. 변수 정의 및 관련 주석을 쉽게 찾을 수 있습니다
  2. 독자는이 변수가 다른 곳에서는 사용되지 않는다는 것을 알고 있습니다 (예상되는 의존성이 없음)
  3. 코드를 작성하거나 편집 할 때 루프 외부에서 동일한 변수 이름을 사용하여 해당 변수를 참조 할 가능성이 없습니다. 그렇지 않으면 오류가 발생할 수 있습니다.

효율 비트의 경우, 컴파일러는 생성 된 최적화 된 코드에서 루프 외부의 정의를 생성하는 것이 현명합니다. 루프 반복마다 변수가 생성되지는 않습니다.


4

사람들은 가능한 한 사용에 가깝다고 말합니다 . 최소한 범위에서 변수를 선언하면 약간의 오버 헤드가 발생할 수 있기 때문에 항상 그렇게해야한다고 말하지는 않습니다.이 문장의 주요 이유는 가독성과 변수 제공입니다. 당신이 할 수있는 가장 작은 범위.


4

가독성에 도움이되지만이 경우 가독성이 주요 고려 사항이 아니며 최신 IDE에서는이 규칙이 필요하지 않습니다.

주요 관심사는 초기화되지 않은 변수입니다. 변수를 초기화에서 너무 멀리 선언하면 모든 종류의 잠재적 인 문제가 발생합니다. 이전에 RAM에 있던 일이나 함수에서 더 높은 계산 결과 또는 누군가가 컴파일러가 불평하는 것을 막기 위해 누군가가 넣은 더미 초기화 (0과 같은)로 실수로 작업 한 것을 알 수 있습니다. 사람들은 해당 변수에 대한 암시 적 전제 조건을 인식하지 않고 선언과 사용법 사이에 코드를 삽입합니다. 최악의 경우, 그 사용법은 테스트에서 작동하지만 현장에서는 실패합니다.

변수를 가능한 한 작은 범위 내에서 선언하고 선언 시점에서 적절한 값으로 초기화하면 많은 유지 관리 문제가 발생하지 않습니다. 가독성을 향상 시킨다는 사실은 단지 좋은 부작용입니다.


1

"필수"가 아닙니다. 그것은 단지 의견 일뿐입니다. 예를 들어, 메서드의 첫 번째 줄에 모든 변수를 선언하고 해당 변수로 수행 할 작업을 설명 할 수 있습니다 (물론 카운터가 아닌 경우). 당신이 들었던 다른 사람들은 (당신이 쓴 두 번째 예에서와 같이) 가능한 한 그들의 사용에 가깝게두기를 좋아합니다. 어쨌든, 당신이 제공하는 첫 번째 예는 분명히 "오류"입니다 (이해하면 이해하는 데 오버 헤드가 발생할 것이라는 점에서).

당신은 단순히 길을 선택하고 따라야합니다.


2
그냥 의견 이 아니야 ? 소프트웨어 엔지니어링 연구는 적어도 1980 년대 이후로 실시간과 버그 수의 관계를 문서화하지 않았습니까?
Mike Sherrill 'Cat Recall'10

1

두 예제는 기능적으로 다른 코드이며 서로 호환되지 않습니다. (예제를 제거하면 차이없이 구별 할 수 있지만 사소한 코드에서는 차이가 있습니다.) "... 가능한 한"으로 표시된대로 사이트 규칙은 항상 범위 고려 사항에 종속됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.