[TIL-011] List<String> → List<int> 타입 변환 오류 해결 방법

2025.03.12 - [TIL(Today I Learned)] - [TIL-008] Dart 실전 문법 파헤치기 - 타입 변환 메서드

 

[TIL-008] Dart 실전 문법 파헤치기 - 타입 변환 메서드

알고리즘이나 이전에 했던 콘솔 쇼핑몰처럼 코드를 작성할 때 타입을 변경해야 하는 경우가 생각보다 많다.예를 들어, 사용자의 입력 값을 가져오면 값이 1이지만 타입은 숫자가 아니라 문자로

skyhyunjinlee.tistory.com

 

상황

  • List<String>의 리스트가 있다.
  • 요소의 타입은 String이지만 값은 숫자이다. 즉, ['1', '2', '3', '4', '5']이다.
  • 리스트의 타입을 List<int>로 반환하는 함수를 만들어보자.

 

문제 코드

List<int> convertFromStringtoNumber(List<String> strNums) {
  List<int> intNums =
      strNums.map((value) {
        return int.tryParse(value);
      }).toList();

  return intNums;
}

void main() {
  List<String> strNums = ['1', '2', '3', '4', '5'];
  
  var newList = convertFromStringtoNumber(strNums);
  print('함수 반환 타입: ${newList.runtimeType}');
}

설명

  • strNums.map()을 이용하여 요소의 값을 가져옴
  • Stringint를 위해 int.tryParse()를 이용
  • toList()로 리스트 타입으로 변환

오류

map의 반환 값의 타입이 <int?>이기 때문에 에러가 발생한다.

etc-image-0

  • List<int?> 유형의 값은 List<int> 유형의 변수에 할당할 수 없습니다.
  • 변수의 유형을 변경하거나 오른쪽 유형을 List<int>로 캐스팅해 보세요.

 

원인 파악

int.tryParse()의 반환 값의 타입이 문제였다.

공식문서를 보면

int? tryParse(
  String source, {
  int? radix,
})

처럼 정의하고 있다.

즉, int.tryParse()int타입을 반환하지만 nullableint를 반환한다는 것이었다.

 

해결 방법

int.parse 사용

List<int> intNums =
  strNums.map((value) {
    return int.parse(value);
  }).toList();
  • int.parse는 non-nullable한 int타입을 반환하기 때문에 해결할 수 있다.

 

!(느낌표) 사용

List<int> intNums =
  strNums.map((value) {
    return int.tryParse(value)!;
  }).toList();
  • !를 사용해 int.tryParse()의 반환 타입이 절대 null이 아니라고 단언을 하면 해결할 수 있다.
  • 정말 null이 아닌 경우에 사용해야 에러가 발생하지 않는다.

 

cast<T> 사용

  • cast메서드는 collection(List, Set, Map 등)의 요소의 타입을 변경할 때 사용하는 메서드.
  • 하지만 실제로 타입을 변경하는 것이 아니라 런타임 때 컴파일러에게 타입을 변경한다고 알려주는 역할만 한다.
  • 알려주는 역할만 하므로 실제 데이터 타입과 다르면 에러가 발생한다.  
List<int> intNums =
  strNums.map((value) {
    return int.tryParse(value);
  }).cast<int>().toList();
  • cast<int>를 사용해 map에서 반환한 타입인 Iterable<int?>Iterable<int>로 변경한다고 컴파일러에게 알려주면 해결할 수 있다.

 

📣 주의 할 점

void main() {
  List<dynamic> dynamicList = ["1", "2", "3"];

  List<int> intList = dynamicList.cast<int>(); // ❌ 런타임 오류!

  print(intList);
}
  • 위에서 언급했듯이 실제로 데이터의 타입을 변경하는 것이 아니다.
  • dynamicList의 요소가 실제로는 String이므로 cast<int>()를 해도 변경되지 않는다.

 

결과(느낀 점)

메서드는 단순히 용도를 외워 상황에 맞게 사용하는 것만으로는 충분하지 않았다.
그 메서드가 어떻게 구성되어 있는지를 이해해야만, 그것을 진정으로 알고 활용할 수 있었다.

 

실제 개발에서는 이보다 더 복잡한 문제가 발생할 가능성이 크다.
그때 신속하게 문제를 해결하기 위해서는 지금과 같은 과정이 큰 도움이 됐으면 좋겠다.

 

또한, cast메서드는 바꾸고 싶은 타입을 제네릭으로 지정하는 것이 아니라, 기존 데이터의 타입을 제네릭으로 사용하여 타입을 단언하는 용도로 활용된다고 기억하는 것이 더 효과적일 것 같다.