programing

'목록' 유형은 '목록' 유형의 하위 유형이 아닙니다.

css3 2023. 3. 16. 21:42

'목록' 유형은 '목록' 유형 하위 유형이 아닙니다.

Flutter는 처음이라 GitHub 프로젝트를 하나 실행하려고 했는데 다음과 같은 오류가 발생했습니다.

type List dynamic은 List int where 유형의 하위 유형이 아닙니다.

Github 링크

에러 라인

List<int> genreIds;

MediaItem._internalFromJson(Map jsonMap, {MediaType type: MediaType.movie})
      :
        type = type,
        id = jsonMap["id"].toInt(),
        voteAverage = jsonMap["vote_average"].toDouble(),
        title = jsonMap[(type == MediaType.movie ? "title" : "name")],
        posterPath = jsonMap["poster_path"] ?? "",
        backdropPath = jsonMap["backdrop_path"] ?? "",
        overview = jsonMap["overview"],
        releaseDate = jsonMap[(type == MediaType.movie
            ? "release_date"
            : "first_air_date")],

        genreIds = jsonMap["genre_ids"];//in this line

}

위의 코드 파일

바꾸다

genreIds = jsonMap["genre_ids"];

로.

genreIds = jsonMap["genre_ids"].cast<int>();

JSON 맵 또는 목록의 유형에는 구체적인 범용 유형이 없습니다. genreIds필요한 것은List<int>단 한 명도 없다List(또는List<dynamic>따라서 할당하기 전에 값을 필요한 유형으로 설정해야 합니다.

같은 코드에 대해 이 에러를 아직 발견하지 못했다면 아마도 Dart 버전으로 업그레이드했기 때문일 것입니다.--preview-dart-2디폴트가 되었습니다(이전에는 옵트인이었습니다).

보다 우아한 방법은 캐스팅 대신 새로운 목록을 초기화하는 것입니다.

var genreIdsFromJson = jsonMap['genre_ids'];
List<int> genreIdsList = new List<int>.from(genreIdsFromJson);

// then you can use gendreIdsList to the mapping function
// ...

gendreIds = genreIdsList
...

업데이트: 매뉴얼에 따라 주세요.

"모든 요소는 E의 인스턴스여야 합니다.반복 가능한 요소 자체는 모든 요소 유형을 가질 수 있으므로 이 생성자를 사용하여 다음과 같이 목록을 다운캐스트할 수 있습니다.

List<SuperType> superList = ...;
List<SubType> subList =
    new List<SubType>.from(superList.whereType<SubType>());

이 생성자는 grownable이 참이면 grownable 목록을 만들고 그렇지 않으면 고정 길이 목록을 반환합니다.``

업데이트: 캐스팅보다 초기화가 더 좋은 이유 (찬성/반대)

명시적 변환(캐스팅):이 프로세스는 보통 정보 손실 또는 유형 간 변환 실패와 관련되어 있습니다.

새로운 불변의 요소를 창조하는 것이 캐스팅보다 낫다.컴파일 시 유형 관련 버그, 읽기 쉬운 코드, 유지 보수하기 쉬운 코드, 보다 나은 선행 시간(AOT) 컴파일 시 드러납니다.

즉, 유형이 일치하지 않으면 값이 null이 되므로 미리 정의된 메서드를 사용하여 값을 구문 분석하거나 구문 분석하는 것이 좋습니다.한편 오브젝트 또는 값을 명시적으로 캐스팅하면 실행 시 오류가 발생할 수 있습니다.

보다 짧은 처리방법은

genreIds = (jsonMap["genre_ids"] as List)?.map((e) => e as int)?.toList();

그래도 날 좋아하지 않는다면, 시도해봐:

List<int> genreIds = List<int>.from(json.decode(jsonMap["genre_ids"]));

api lib에서 제네릭스를 사용했기 때문에 이 문제를 발견했습니다.대처 방법은 다음과 같습니다.

// I've simplified the get for clarity.  My production lib wraps http so I can set / handle base url, headers, time out, and throw when error codes are returned.

Future<T> get<T>(String resource) async {
  var c = Completer<T>();
  try {
    var uri = Uri.parse('$baseUrl/$resource');
    var response = await http.get(uri);
    T result = json.decode(response.body);
    c.complete(result);
  } catch (e) {
    c.completeError(e);
  }
  return c.future;
}

// Service from my feature lib
Future<Iterable<MyDTO>> fetch() async {
  var c = Completer<Iterable<MyDTO>>();
  try {
    List<MyDTO> result = [];        
    // Use Iterable<dynamic> since we cannot use generics to cast when decoding the response body
    var body = await api.get<Iterable<dynamic>>('my-resource');
    
    // cast to List<Map<String, dynamic>
    var myDTOMaps = List<Map<String, dynamic>>.from(body);

    for (var e in myDTOMaps) {
      MyDTO dto = MyDTO.fromMap(e);
      result.add(dto);
    }
    c.complete(result);
  } catch (e) {
    c.completeError(e);
  }
  return c.future;
}

모든 솔루션이 주어집니다.나는 그것을 실현하기 위한 많은 다른 방법들을 추가하고 싶다.

  1. List<int> genreIds = List<int>.from(source);
  2. List<int> ints = List.castFrom<dynamic, int>(source);
  3. List<int> ints = source.cast<int>();
  4. List<int> ints = source.map((e) => e as int).toList();

이 사용 예에 대해서는, 다음과 같이 기술할 수 있습니다.

List<int> genreIds = List<int>.from(jsonMap["genre_ids"]);

도움이 되길! :)

데이터가 어떤 상태인지 알고 있는 경우 첫 번째 항목 유형을 확인하여 목록이 문자열 등으로 채워져 있는지 확인할 수 있습니다.

if (errors is List && errors.isNotEmpty && errors.first is String) {
    return List<String>.from(errors);
}

json 설정 속성 사용 시 유사한 오류가 발생하였습니다.이렇게 수정했습니다.

jsonMap["propId"][0] as int

이러한 속성은 단일 속성이기 때문에 0이 항상 맞습니다.

언급URL : https://stackoverflow.com/questions/50245187/type-listdynamic-is-not-a-subtype-of-type-listint-where