shared case 스코프의 패턴 변수 진단: 모든 case에서 같은 타입·같은 final로 선언하세요

shared case 스코프의 패턴 변수 진단: 모든 case에서 같은 타입·같은 final로 선언하세요

switch 문에서 여러 case 절이 몸통(body)을 공유할 때, 공유된 코드 안에서 쓰는 변수가 모든 case에 똑같이 선언되어 있지 않으면 값이 없을 수 있어요. Dart 분석기는 이런 상황을 invalid_pattern_variable_in_shared_case_scope 진단으로 알려줘요.

출처: invalid_pattern_variable_in_shared_case_scope

본문

설명

분석기는 여러 case 절이 하나의 몸통을 공유할 때, 그 중 적어도 하나가 공유된 문장에서 참조되는 변수를 선언하는데 — 그 변수가 모든 case 절에 선언되지 않았거나, 아니면 방식이 제각각일 때 이 진단을 만들어요.

변수가 모든 case 절에 선언되지 않았다면, 변수를 선언하지 않은 절이 매치되어 몸통을 실행하는 경우에는 그 변수에 값이 없어요. 여기에는 절들 중 하나가 default 절인 경우도 포함돼요.

변수가 제각각 선언됐다면 — 어떤 case에서는 final이고 다른 case에서는 final이 아니거나, case마다 타입이 다르다면 — 그 변수의 타입과 final 여부가 무엇이어야 하는지 의미가 정의되지 않아요.

예시

다음 코드는 변수 acase 절 중 하나에만 선언되어 있어서, 두 번째 절이 x에 매치되면 값이 없기 때문에 이 진단을 만들어요.

void f(Object? x) {
  switch (x) {
    case int a when a > 0:
    case 0:
      a;
  }
}

다음 코드는 변수 adefault 절에 선언되어 있지 않아서, 다른 절들이 x에 매치되지 않아 몸통이 실행되는 경우 값이 없기 때문에 이 진단을 만들어요.

void f(Object? x) {
  switch (x) {
    case int a when a > 0:
    default:
      a;
  }
}

다음 코드는 다른 case 그룹이 라벨에서 제어 흐름을 이어받아 몸통이 실행될 때 변수 a에 값이 없기 때문에 이 진단을 만들어요.

void f(Object? x) {
  switch (x) {
    someLabel:
    case int a when a > 0:
      a;
    case int b when b < 0:
      continue someLabel;
  }
}

다음 코드는 변수 a가 모든 case 절에서 할당되긴 하지만, 절마다 연관된 타입이 같지 않기 때문에 이 진단을 만들어요.

void f(Object? x) {
  switch (x) {
    case int a when a < 0:
    case num a when a > 0:
      a;
  }
}

다음 코드는 변수 a가 첫 번째 case 절에서는 final이고 두 번째 case 절에서는 final이 아니기 때문에 이 진단을 만들어요.

void f(Object? x) {
  switch (x) {
    case final int a when a < 0:
    case int a when a > 0:
      a;
  }
}

흔한 해결 방법

변수가 모든 case에 선언되어 있지 않고 그 변수를 문장에서 참조해야 한다면, 다른 case에도 선언해 주세요.

void f(Object? x) {
  switch (x) {
    case int a when a > 0:
    case int a when a == 0:
      a;
  }
}

변수가 모든 case에 선언되어 있지 않지만 문장에서 참조할 필요가 없다면, 그 참조를 지우고 다른 case의 선언도 지워 주세요.

void f(int x) {
  switch (x) {
    case > 0:
    case 0:
  }
}

변수의 타입이 서로 다르다면, 변수가 가져야 할 타입을 정하고 case들을 일관되게 만들어 주세요.

void f(Object? x) {
  switch (x) {
    case num a when a < 0:
    case num a when a > 0:
      a;
  }
}

변수의 final 여부가 서로 다르다면, final로 할지 말지 정하고 case들을 일관되게 만들어 주세요.

void f(Object? x) {
  switch (x) {
    case final int a when a < 0:
    case final int a when a > 0:
      a;
  }
}

더 알아보기