为啥 toList() 在 Dart 中创建一个 List<dynamic>?

Posted

技术标签:

【中文标题】为啥 toList() 在 Dart 中创建一个 List<dynamic>?【英文标题】:Why toList() creates a List<dynamic> in Dart?为什么 toList() 在 Dart 中创建一个 List<dynamic>? 【发布时间】:2019-05-24 09:02:43 【问题描述】:

我有这个方法,它在 Dart 2 中编译没有问题。但是在运行时我收到以下错误

类型“List&lt;dynamic&gt;”不是类型“List&lt;ExchangeRate&gt;”的子类型

正如您在代码中看到的,我在 .map() 中创建并返回新的 ExchangeRate 对象,然后返回一个 rateEntries.toList(),我希望它的类型为 List&lt;ExchangeRate&gt;,但它似乎被推断为 @ 类型987654326@!!!

@override
Future<List<ExchangeRate>> getExchangeRatesAt(DateTime time, Currency baseCurrency) async 
  final http.Client client = http.Client();
  final String uri = "some uri ...";
  return await client
    .get(uri)
    .then((response) 
      var jsonEntries = json.decode(response.body) as Map<String, dynamic>;
      var rateJsonEntries = jsonEntries["rates"].entries.toList();
      var rateEntries = rateJsonEntries.map((x) 
        return new ExchangeRate(x.value.toDouble());
      );
      return rateEntries.toList(); // WHY IS IT RETURNING A List<dynamic> here?
    )
    .catchError((e) => print(e))
    .whenComplete(() => client.close());

但是,如果我专门将其转换为 ExchangeRate 就可以了。

    return rateEntries.toList().cast<ExchangeRate>();

最后的这个选角对我来说似乎是多余的,我为什么需要它?

【问题讨论】:

【参考方案1】:

好吧,似乎需要强制转换才能完全定义类型。

但是,如果添加以下任何 sn-ps,则可以避免强制转换:

    rateJsonEntries 变量提供正确的类型

    List&lt;dynamic&gt; rateJsonEntries = jsonEntries["rates"].entries.toList();

    无论出于何种原因,这对我来说都有效。

    map()方法中添加参数类型

    var rateEntries = rateJsonEntries.map<ExchangeRate>((x) return new ExchangeRate(x.value.toDouble()); );

【讨论】:

谢谢。您的两种解决方法都有效,因为无需添加.cast&lt;ExchangeRate&gt;()。我更喜欢你的第二种解决方法。但是,我不明白为什么 Dart 需要为.map(即.map&lt;ExchangeRate&gt;())指定类型才能输出正确的类型而不是dynamic 问题是它可能是由于类型推断问题。在第一种情况下添加List&lt;dynamic&gt; 毫无意义。如果你只是在那里使用var 并执行print(rateJsonEntries.runtimeType),它会准确打印List&lt;dynamic&gt;。正如 Jonah 在 ***.com/questions/49603021 中所说,类型推断似乎以一种意想不到的方式失败。 感谢您提供的链接,该链接解释了幕后可能发生的事情。所以我接受你的第二个解决方案作为这个问题的答案。

以上是关于为啥 toList() 在 Dart 中创建一个 List<dynamic>?的主要内容,如果未能解决你的问题,请参考以下文章

Dart,如何在你自己的函数中创建一个返回的未来?

如何在 Dart 中创建 StreamTransformer?

如何在 Dart 中创建一个空 Set

在 List 中创建 List 的第一个元素 - Flutter、Dart

无法在 Android Studio 4.0 中创建 Dart 项目

比较在 Dart 中创建单例的方法