생성자가 자기 자신으로 리다이렉트할 수 없음

생성자가 자기 자신으로 리다이렉트할 수 없음 (recursive_constructor_redirect)

이 문서는 Dart 분석기(analyzer)가 내는 recursive_constructor_redirect 진단(diagnostic)을 설명하는 문서예요. 생성자(constructor)가 직접 또는 간접적으로 자기 자신에게 리다이렉트하면 무한 루프가 생기는데요. 어떤 상황에서 발생하고 어떻게 고치는지 함께 알아볼게요.

출처: recursive_constructor_redirect

본문

진단 메시지

Constructors can't redirect to themselves either directly or indirectly.

생성자는 직접 또는 간접적으로 자기 자신에게 리다이렉트할 수 없어요.

설명

분석기는 어떤 생성자가 직접 또는 간접적으로 자기 자신에게 리다이렉트할 때 이 진단을 만들어 내요. 리다이렉트가 서로를 계속 물고 돌면 결국 실제로 호출될 생성자가 없어지면서 무한 루프가 생기거든요.

예시

다음 코드는 제네러티브(generative) 생성자 C.aC.b가 서로에게 리다이렉트해서 이 진단을 만들어 내요.

class C {
  C.a() : this.b();
  C.b() : this.a();
}

다음 코드는 팩토리(factory) 생성자 AB가 서로에게 리다이렉트해서 이 진단을 만들어 내요.

abstract class A {
  factory A() = B;
}

class B implements A {
  factory B() = A;
  B.named();
}

일반적인 해결 방법

제네러티브 생성자의 경우, 두 생성자 중 적어도 하나는 다른 생성자로 리다이렉트하지 않도록 정의해서 고리를 끊으면 돼요.

class C {
  C.a() : this.b();
  C.b();
}

팩토리 생성자의 경우에는 두 팩토리 중 적어도 하나를 다음 중 한 가지 방식으로 바꿔서 고리를 끊어요.

  • 제네러티브 생성자로 리다이렉트하기:
abstract class A {
  factory A() = B;
}

class B implements A {
  factory B() = B.named;
  B.named();
}
  • 다른 생성자로 리다이렉트하지 않기:
abstract class A {
  factory A() = B;
}

class B implements A {
  factory B() {
    return B.named();
  }

  B.named();
}
  • 팩토리 생성자가 아니게 하기:
abstract class A {
  factory A() = B;
}

class B implements A {
  B();
  B.named();
}

더 알아보기