문제

오늘 동료가 내가 만든 2개의 중첩 for 루프를 통해 흐름을 제어하기 위해 레이블 문을 사용하도록 코드를 리팩터링하라고 제안했습니다.나는 개인적으로 프로그램의 가독성을 떨어뜨린다고 생각하기 때문에 이전에 사용해 본 적이 없습니다.그러나 주장이 충분히 확실하다면 사용에 대한 마음을 바꿀 의향이 있습니다.라벨 설명에 대한 사람들의 의견은 무엇입니까?

도움이 되었습니까?

해결책

두 개의 루프(또는 스위치 문이 포함된 루프)를 건너뛸 수 있으면 많은 알고리즘이 더 쉽게 표현됩니다.그것에 대해 기분 나쁘게 생각하지 마십시오.반면에 지나치게 복잡한 솔루션을 나타낼 수도 있습니다.그러니 뒤로 물러서서 문제를 살펴보세요.

어떤 사람들은 모든 루프에 대해 "단일 입력, 단일 종료" 접근 방식을 선호합니다.즉, 루프에 대한 중단(및 계속) 및 조기 반환을 모두 피하는 것입니다.이로 인해 일부 중복된 코드가 발생할 수 있습니다.

내가 강력히 피하고 싶은 것은 보조 변수를 도입하는 것입니다.상태 내에서 제어 흐름을 숨기면 혼란이 가중됩니다.

레이블이 지정된 루프를 두 가지 방법으로 분할하는 것은 어려울 수 있습니다.예외는 아마도 너무 무거울 것입니다.단일 진입, 단일 출구 접근 방식을 시도해 보세요.

다른 팁

레이블은 goto와 유사합니다.코드를 더 빠르게 만들 때만 아껴서 사용하세요. 그리고 더 중요한 것은, 더 이해하기 쉽고,

예를 들어, 6개 레벨 깊이의 큰 루프에 있고 나머지 루프를 완료하는 데 무의미하게 만드는 조건에 직면한 경우 루프를 일찍 종료하기 위해 조건문에 6개의 추가 트랩 도어를 갖는 것은 의미가 없습니다.

라벨(및 goto's)은 나쁜 것이 아닙니다. 단지 사람들이 라벨을 나쁜 방식으로 사용하는 경우가 있을 뿐입니다.대부분의 경우 우리는 실제로 코드를 작성하려고 노력하므로 귀하와 다음 프로그래머가 이해할 수 있습니다.초고속으로 만드는 것은 부차적인 관심사입니다(성급한 최적화에 주의하세요).

레이블(및 goto)이 잘못 사용되면 코드 읽기가 어려워지고 이는 귀하와 다음 개발자에게 슬픔을 안겨줍니다.컴파일러는 신경 쓰지 않습니다.

라벨이 필요한 경우는 거의 없으며 거의 ​​사용되지 않기 때문에 혼란스러울 수 있습니다.그러나 하나를 사용해야 한다면 하나를 사용하십시오.

지금:이것은 컴파일되고 실행됩니다.

class MyFirstJavaProg {  
        public static void main(String args[]) {
           http://www.javacoffeebreak.com/java101/java101.html
           System.out.println("Hello World!");
        }
}

라벨에 대한 대안이 무엇인지 듣고 싶습니다.나는 이것이 "가능한 한 빨리 복귀하는 것"과 "가능한 한 빨리 복귀"라는 논쟁으로 귀결될 것이라고 생각합니다."변수를 사용하여 반환 값을 보유하고 마지막에만 반환합니다."

중첩 루프가 있는 경우 레이블은 꽤 표준적입니다.실제로 가독성이 떨어지는 유일한 방법은 다른 개발자가 이전에 본 적이 없고 그 의미를 이해하지 못하는 경우입니다.

나는 Java 코드에서 "야생"으로 사용되는 레이블을 본 적이 없습니다.중첩된 루프를 정말로 중단하고 싶다면 early return 문이 원하는 대로 작동하도록 메서드를 리팩터링할 수 있는지 확인하세요.

엄밀히 따지면 조기 복귀와 라벨링 사이에는 큰 차이가 없는 것 같아요.그러나 실제로 거의 모든 Java 개발자는 조기 복귀를 경험했으며 그것이 무엇을 하는지 알고 있습니다.나는 많은 개발자들이 적어도 라벨에 놀라고 아마도 혼란스러워할 것이라고 생각합니다.

나는 학교에서 단일 입력/단일 종료 정통을 배웠지만 그 이후로 코드를 단순화하고 더 명확하게 만드는 방법으로 조기 반환 문과 루프 중단을 높이 평가하게 되었습니다.

나는 일부 위치에서 이를 선호한다고 주장하는데, 이 예에서 특히 유용하다는 것을 알았습니다.


nextItem: for(CartItem item : user.getCart()) {

  nextCondition : for(PurchaseCondition cond : item.getConditions()) {
     if(!cond.check())
        continue nextItem;
     else
        continue nextCondition;

  }
  purchasedItems.add(item);
}

새로운 for-each 루프를 사용하면 레이블이 정말 명확해질 수 있다고 생각합니다.

예를 들어:

sentence: for(Sentence sentence: paragraph) {
  for(String word: sentence) {
    // do something
    if(isDone()) {
      continue sentence;
    }
  }
}

새로운 for-each의 변수와 레이블을 동일하게 설정하면 정말 명확해 보인다고 생각합니다.사실, Java는 사악하고 각 변수에 대해 암시적 레이블을 추가해야 할 수도 있습니다.

Sieve 메소드 구현을 위해 Java 레이블이 붙은 루프를 사용하여 소수(프로젝트 오일러 수학 문제 중 하나에 대해 수행됨)를 찾아 중첩 루프에 비해 10배 더 빠르게 만들었습니다.예를 들어 if(특정 조건)는 외부 루프로 돌아갑니다.

private static void testByFactoring() {
    primes: for (int ctr = 0; ctr < m_toFactor.length; ctr++) {
        int toTest = m_toFactor[ctr];
        for (int ctr2 = 0; ctr2 < m_divisors.length; ctr2++) {
            // max (int) Math.sqrt(m_numberToTest) + 1 iterations
            if (toTest != m_divisors[ctr2]
                        && toTest % m_divisors[ctr2] == 0) {
                continue primes; 
            }
        } // end of the divisor loop
    } // end of primes loop
} // method

나는 C++ 프로그래머에게 레이블이 있는 루프가 얼마나 나쁜지 물었습니다. 그는 레이블이 있는 루프를 드물게 사용하겠다고 말했지만 때로는 유용할 수 있다고 말했습니다.예를 들어, 3개의 중첩 루프가 있고 특정 조건에 대해 가장 바깥쪽 루프로 돌아가고 싶은 경우입니다.

따라서 그것들은 각자의 용도가 있으며 해결하려는 문제에 따라 다릅니다.

내 코드에는 라벨을 사용하지 않습니다.나는 가드를 생성하고 초기화하는 것을 선호합니다 없는 또는 기타 특이한 값.이 가드는 종종 결과 객체입니다.동료 중 라벨을 사용하는 것을 본 적이 없으며 저장소에서도 라벨을 발견하지 못했습니다.실제로 코딩 스타일에 따라 다릅니다.제 생각에는 레이블을 사용하면 일반적인 구성이 아니고 일반적으로 Java에서 사용되지 않으므로 가독성이 떨어질 것입니다.

예, 라벨을 사용해야 하는 특별한 이유가 없는 한 라벨 사용을 피해야 합니다(알고리즘 구현을 단순화하는 예가 적절함).그러한 경우에는 누군가가 나중에 와서 "코드 개선" 또는 "코드 냄새 제거"라는 개념을 망쳐 놓지 않도록 그 이유를 설명하기 위해 충분한 설명이나 기타 문서를 추가하는 것이 좋습니다. 다른 잠재적으로 BS 변명.

나는 이런 종류의 질문을 언제 삼항 if를 사용해야 하는지, 사용하지 말아야 하는지를 결정하는 것과 동일시합니다.주된 근거는 가독성을 방해할 수 있으며 프로그래머가 합리적인 방식으로 이름을 지정하는 데 매우 주의하지 않는 한 레이블과 같은 규칙을 사용하면 상황이 훨씬 더 악화될 수 있다는 것입니다.'nextCondition'과 'nextItem'을 사용하는 예에서 라벨 이름으로 'loop1'과 'loop2'를 사용했다고 가정합니다.

개인적으로 레이블은 Assembly나 BASIC 및 기타 유사하게 제한된 언어 외에는 나에게 별로 의미가 없는 기능 중 하나입니다.Java에는 더 많은 기존/정규 루프 및 제어 구성이 있습니다.

나는 레이블이 테스트에서 일반적인 설정을 분리하고 단계 및 그룹 관련 설명을 연습하고 확인하는 데 때때로 유용하다는 것을 알았습니다.예를 들어 BDD 용어를 사용하면 다음과 같습니다.

@Test
public void should_Clear_Cached_Element() throws Exception {
    given: {
        elementStream = defaultStream();
        elementStream.readElement();
        Assume.assumeNotNull(elementStream.lastRead());
    }
    when:
        elementStream.clearLast();
    then:
        assertThat(elementStream.lastRead()).isEmpty();
}

형식 선택은 다양할 수 있지만 핵심 아이디어는 레이블이 이 경우 테스트를 구성하는 논리적 섹션 간에 주석보다 눈에 띄는 구별을 제공한다는 것입니다.내 생각 엔 스팍 라이브러리는 바로 이 기능을 기반으로 테스트 단계를 선언합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top