为啥 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<dynamic>
”不是类型“List<ExchangeRate>
”的子类型
正如您在代码中看到的,我在 .map()
中创建并返回新的 ExchangeRate 对象,然后返回一个 rateEntries.toList()
,我希望它的类型为 List<ExchangeRate>
,但它似乎被推断为 @ 类型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<dynamic> rateJsonEntries = jsonEntries["rates"].entries.toList();
无论出于何种原因,这对我来说都有效。
在map()
方法中添加参数类型
var rateEntries = rateJsonEntries.map<ExchangeRate>((x)
return new ExchangeRate(x.value.toDouble());
);
【讨论】:
谢谢。您的两种解决方法都有效,因为无需添加.cast<ExchangeRate>()
。我更喜欢你的第二种解决方法。但是,我不明白为什么 Dart 需要为.map
(即.map<ExchangeRate>()
)指定类型才能输出正确的类型而不是dynamic
。
问题是它可能是由于类型推断问题。在第一种情况下添加List<dynamic>
毫无意义。如果你只是在那里使用var
并执行print(rateJsonEntries.runtimeType)
,它会准确打印List<dynamic>
。正如 Jonah 在 ***.com/questions/49603021 中所说,类型推断似乎以一种意想不到的方式失败。
感谢您提供的链接,该链接解释了幕后可能发生的事情。所以我接受你的第二个解决方案作为这个问题的答案。以上是关于为啥 toList() 在 Dart 中创建一个 List<dynamic>?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Dart 中创建 StreamTransformer?
在 List 中创建 List 的第一个元素 - Flutter、Dart