flutter 类型“List< dynamic>”不是类型“List”的子类型< int>,其中

nle07wnf  于 2022-12-24  发布在  Flutter
关注(0)|答案(7)|浏览(207)

我是Flutter的新手,我尝试运行一个GitHub项目,但出现了如下错误:
类型List dynamic不是类型List int的子类型,其中。
Github Link

错误行

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

}

Above code File

zzlelutf

zzlelutf1#

变更

genreIds = jsonMap["genre_ids"];

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

JSONMap或列表中的类型没有具体的泛型类型。genreIds需要List<int>,而不是List(或List<dynamic>),因此在赋值之前,需要将值转换为所需的类型。
如果您之前没有在相同代码中看到此错误,则可能是因为您升级到了Dart版本,其中--preview-dart-2成为默认值(之前是选择加入的)

fzwojiic

fzwojiic2#

一个更优雅的方法也可以是初始化新的List而不是强制转换。

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

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

gendreIds = genreIdsList
...

更新:As per the documentation
''所有的元素都应该是E的示例。可迭代的元素本身可以有任何元素类型,所以这个构造函数可以用来向下转换List,例如:

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

此构造函数在growable为true时创建可增长列表;否则,它返回一个固定长度的列表。
更新:为什么初始化比强制转换更好?(优点/缺点)
显式转换(强制转换):该过程通常与信息丢失或无法在类型之间转换有关
创建新的不可变元素比强制转换好。在编译时发现与类型相关的错误,代码更可读,代码更易维护,更好的提前(AOT)编译。
也就是说,最好尝试解析或使用预定义方法解析值,因为如果类型不匹配,则值将为null。另一方面,显式强制转换对象或值可能会在运行时引发错误。

cgfeq70w

cgfeq70w3#

一个更简短的处理方法是

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

ilmyapht4#

如果你仍然像我一样不成功,试试:
第一个月

mxg2im7a

mxg2im7a5#

我遇到这个问题是因为我在API库中使用了泛型,下面是我的解决方法:

// 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;
}
clj7thdc

clj7thdc6#

考虑到所有的解决方案。我想补充许多其他不同的方法来实现同样的目标。
1.第一个月

  1. List<int> ints = List.castFrom<dynamic, int>(source);
  2. List<int> ints = source.cast<int>();
  3. List<int> ints = source.map((e) => e as int).toList();
    对于此用例,您可以编写:
    List<int> genreIds = List<int>.from(jsonMap["genre_ids"]);
    希望有帮助!:)
oug3syen

oug3syen7#

我在使用json设置属性时遇到了类似的错误,我用以下代码修复了它:

jsonMap["propId"][0] as int

它们是单一属性,因此0始终是正确的。

相关问题