【问题标题】:type 'List<dynamic>' is not a subtype of type 'List<int>' wheretype 'List<dynamic>' 不是 type 'List<int>' 的子类型,其中
【发布时间】:2018-10-19 02:07:42
【问题描述】:

我是 Flutter 的新手,我尝试运行一个 GitHub 项目,但是遇到了一个错误,比如 type List dynamic is not a subtype of List int where。 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

任何帮助将不胜感激,在此先感谢您。

【问题讨论】:

    标签: json list flutter dart dynamic


    【解决方案1】:

    改变

    genreIds = jsonMap["genre_ids"];
    

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

    JSON 映射或列表中的类型没有具体的泛型类型。 genreIds 需要 List&lt;int&gt; 而不是 List(或 List&lt;dynamic&gt;),因此您需要先将值设为所需的类型,然后才能分配它。

    如果您之前没有看到相同代码的此错误,那么可能是因为您升级到了 --preview-dart-2 成为默认值的 Dart 版本(之前是选择加入的)

    【讨论】:

    • 这仍然有效吗? List 中似乎没有演员表功能
    • cast 只存在了很短的时间。有关详细信息,请参阅github.com/dart-lang/site-www/issues/736
    • @GünterZöchbauer 如果演员表只存在很短的时间,现在应该使用什么?在我的情况下,我试图将 List 转换为 List 并且“as”不起作用,仍然必须使用“.cast”?
    • 您是否在您之前查看了我评论中的链接?也许new List&lt;DocumentReference&gt;(myDynamicList)
    • 每天我都在搜索与 Flutter / Dart 相关的内容,先生,您的回答让我有了更好的理解。谢谢你。与@paresh 的回答相关,我们可以使用可识别空值的运算符,例如:genreIds = jsonMap["genre_ids"]?.cast&lt;int&gt;();
    【解决方案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
    ...
    

    更新: As per the documentation

    `` 所有元素都应该是 E 的实例。可迭代的元素本身可以具有任何元素类型,因此可以使用此构造函数来向下转换 List,例如:

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

    这个构造函数在growable为真时创建一个可增长列表;否则,它返回一个固定长度的列表。 ``

    更新:为什么初始化比强制转换更好? (优点/缺点)

    显式转换(强制转换):该过程通常与信息丢失或类型之间转换失败有关

    创建新的不可变元素比强制转换要好。在编译时揭示与类型相关的错误、更易读的代码、更可维护的代码、更好的提前 (AOT) 编译。

    即最好尝试使用预定义的方法解析或解析值,因为如果类型不匹配,则该值将为空。另一方面,显式转换对象或值可能会在运行时引发错误。

    【讨论】:

    • 甚至 List.from(genreIdsFromJson ?? []) 来处理地图的 'genre_ids' 键没有元素的情况
    • 您可以在 from(genreIdsFromJson) 方法中添加一些验证。根据情况,您可以在返回相应对象之前进行检查,也可以使用内联条件返回默认值(可能是 null / 空字符串),例如FooType.from(json['genreIdsFromJson']) ? FooType.from(json['genreIdsFromJson']) : null.
    • 这是一个非常有趣的答案,您介意添加与演员阵容相比的优点/缺点吗?谢谢!
    • @Edi 在零安全性下您的答案有何变化?为了满足编译器的要求,我仍然必须为 json 查找添加强制转换:List&lt;Int&gt;.from(jsonMap['genre_ids'] as List) 并在访问映射条目之前进行空检查。
    【解决方案3】:

    更短的处理方式是

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

    【讨论】:

      【解决方案4】:

      我按照cast&lt;Type&gt;() 的建议做了,它运行良好了一段时间。虽然我遇到了一个错误,如果映射中键的值为空(例如,未找到并抛出错误)

      要解决此问题,您可以进行丑陋的内联空值检查:

      这里是实现这一点的更清洁和更 Dartful 的方法是使用 null-aware ?. 运算符:

      尝试这样做(此类型转换修复并修复了null 问题):

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

      而不是

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

      【讨论】:

        【解决方案5】:

        我在使用 json 设置属性时遇到了类似的错误。我用这个修复了它:

        jsonMap["propId"][0] as int
        

        它们是单个属性,所以 0 总是正确的。

        【讨论】:

        • 这甚至没有远程连接到这个问题。
        猜你喜欢
        • 2021-08-25
        • 2019-01-26
        • 2021-11-26
        • 1970-01-01
        • 2021-08-29
        • 2021-01-22
        • 2019-05-02
        • 2019-09-02
        • 1970-01-01
        相关资源
        最近更新 更多