【问题标题】:How to cast <dynamic> to List<String>?如何将 <dynamic> 转换为 List<String>?
【发布时间】:2020-05-23 03:33:03
【问题描述】:

我有一个记录类来解析来自 Firestore 的对象。我的课程的精简版如下所示:

class BusinessRecord {
  BusinessRecord.fromMap(Map<String, dynamic> map, {this.reference})
      : assert(map['name'] != null),
        name = map['name'] as String,
        categories = map['categories'] as List<String>;

  BusinessRecord.fromSnapshot(DocumentSnapshot snapshot)
      : this.fromMap(snapshot.data, reference: snapshot.reference);

  final String name;
  final DocumentReference reference;
  final List<String> categories;
}

这编译得很好,但是当它运行时我得到一个运行时错误:

type List&lt;dynamic&gt; is not a subtype of type 'List&lt;String&gt;' in type cast

如果我只使用categories = map['categories'];,我会得到一个编译错误:The initializer type 'dynamic' can't be assigned to the field type 'List&lt;String&gt;'

我的 Firestore 对象上的categories 是一个字符串列表。我该如何正确投射?

编辑:以下是我使用实际编译的代码时的异常情况:

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    恕我直言,您不应该转换列表,而是一个一个地转换它的孩子,例如:

    更新

    ...
    ...
    categories = (map['categories'] as List)?.map((item) => item as String)?.toList();
    ...
    ...
    

    【讨论】:

    • 如果我尝试categories = map['categories'].map((category) =&gt; category as String);,我会得到The initializer type 'dynamic' can't be assigned to the field type 'List&lt;String&gt;'。如果我尝试categories = (map['categories'] as List&lt;dynamic&gt;).map((category) =&gt; category as String);,我会得到The initializer type 'Iterable&lt;String&gt;' can't be assigned to the field type 'List&lt;String&gt;'
    • 这两个都是编译时错误——没有堆栈跟踪。当可编译代码运行时,我已经用 VSCode 中异常的屏幕截图更新了问题。
    • 谢谢!您更新的示例效果很好。我必须添加的一项修改(可能是因为我使用的是github.com/flutter/flutter/blob/master/analysis_options.yaml)是为Listitem 的类型指定dynamiccategories = (map['categories'] as List&lt;dynamic&gt;)?.map((dynamic item) =&gt; item as String)?.toList();。也很抱歉延迟回复 - 我休假了 2 周。
    【解决方案2】:

    简单回答:

    您可以使用扩展运算符,例如[...json["data"]]

    完整示例:

    final Map<dynamic, dynamic> json = {
      "name": "alice",
      "data": ["foo", "bar", "baz"],
    };
    
    // method 1, cast while mapping:
    final data1 = (json["data"] as List)?.map((e) => e as String)?.toList();
    print("method 1 prints: $data1");
    
    // method 2, use spread operator:
    final data2 = [...json["data"]];
    print("method 2 prints: $data2");
    

    输出:

    flutter: method 1 prints: [foo, bar, baz]
    flutter: method 2 prints: [foo, bar, baz]
    

    【讨论】:

      【解决方案3】:

      更简单的答案,据我所知也是建议的方式。

      List<String> categoriesList = List<String>.from(map['categories'] as List);
      
      

      注意“as List”可能甚至不需要。

      【讨论】:

        猜你喜欢
        • 2021-05-20
        • 2020-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-27
        • 1970-01-01
        • 2014-11-19
        • 2020-06-02
        相关资源
        最近更新 更多