首页 > 解决方案 > Dart 使用 putIfAbsent 初始化 Map 中的列表

问题描述

我有一张列表地图,例如

HashMap exampleMap = new HashMap<String, List<Foo>>();

如果密钥不存在,我想初始化一个新列表,我一直在尝试 putIfAbsent 的变体,但到目前为止没有成功

exampleMap.putIfAbsent('bar', () => []);

我的最终目标是将项目添加到列表中,但需要先初始化列表

exampleMap['bar'].add(fooItem);

标签: flutterdart

解决方案


有几件事是错误的:

HashMap exampleMap = new HashMap<String, List<Foo>>();

这声明exampleMap是一个HashMap<dynamic, dynamic>. (请参阅Why is dart wrongly inferring my generic parameter type?了解原因。)

寓意是:如果要显式声明类型,则必须在任何地方都显式。你不能半途而废。否则,只需使用var并允许从右侧推断变量的类型。

稍后当你这样做时:

exampleMap.putIfAbsent('bar', () => []);

因为exampleMap的静态(在编译时已知)类型是HashMap<dynamic, dynamic>,所以对于 的值的类型一无所知HashMap() => []因此无法推断匿名函数 ( ) 的返回类型,并且由于它返回一个没有显式类型参数的空列表,因此也无法推断List的元素类型。因此,匿名函数被编译为Function返回 a 的 a List<dynamic>

同时,exampleMap运行时类型实际上是一个HashMap<String, List<Foo>>. 当您执行代码时,putIfAbsent将由于无法安全地在预期的List<dynamic>位置添加 a 而失败。List<Foo>

如果您将原始声明修复为 use var,那么您的putIfAbsent调用应该可以在没有任何额外更改的情况下工作。如果您确实希望exampleMap是静态类型HashMap<dynamic, dynamic>,那么您也可以更改您的putIfAbsent调用以提供空的显式类型ListexampleMap.putIfAbsent('bar', () => <Foo>[])

我还要指出,如果你不允许null在你的值Map,我更喜欢使用??=over putIfAbsent

var exampleMap = HashMap<String, List<Foo>>();
exampleMap['bar'] ??= [];

推荐阅读