Flutter空安全迁移时默认List构造函数不可用报错解决
报错原因
空安全模式下Dart禁用了List(int length)默认构造函数,才会抛出这个错误:
- 空安全上线前,这个构造器会生成指定长度、所有元素初始值为
null的定长列表,是旧版本里很常见的写法。 - 启用空安全后,非空类型的集合不允许出现
null元素,这个会默认生成全null值的构造器直接被从核心API中移除,官方要求替换为列表字面量、List.filled、List.generate这三类不会产生非法null值的列表构造方式。
你代码里的三处List(n)写法,本质只是为了获得n次迭代的执行次数,根本没有使用列表内存储的元素,属于旧版本中“借列表实现循环”的特殊写法,在空安全下需要替换为合法实现。
修改方案
有两种常见改法,第一种是最小改动保留原有链式逻辑,第二种是更高效的规范写法,推荐第二种。
最小改动方案
只需要把所有List(n)替换为List.filled(n, 0)即可,List.filled会生成一个所有元素都为你指定的默认值的定长列表,完全符合空安全要求,其余代码逻辑不需要调整:
List<CardModel> createCards() { List<String> asset = []; List.filled(10, 0).forEach((f) => asset.add('0${(asset.length + 1)}.png')); List.filled(10, 0).forEach((f) => asset.add('0${(asset.length - 10 + 1)}.png')); return List.filled(20, 0).map((f) { int index = Random().nextInt(1000) % asset.length; String _image = 'assets/' + asset[index].substring(asset[index].length - 6); asset.removeAt(index); return CardModel( id: 20 - asset.length - 1, image: _image, key: UniqueKey()); }).toList(); }
这种写法的缺点是会生成三个用完即弃的临时列表,存在不必要的内存开销。
推荐的规范写法
去掉冗余的临时列表,直接用for循环实现固定次数的迭代,最后用List.generate直接生成目标列表,既符合空安全规范,性能也更好,业务逻辑和原代码完全一致:
List<CardModel> createCards() { List<String> asset = []; // 替换原临时列表实现的循环 for (int i = 0; i < 10; i++) { asset.add('0${asset.length + 1}.png'); } for (int i = 0; i < 10; i++) { asset.add('0${asset.length - 10 + 1}.png'); } // 直接生成目标列表,省去map、toList的中间步骤 return List.generate(20, (_) { int index = Random().nextInt(1000) % asset.length; String _image = 'assets/' + asset[index].substring(asset[index].length - 6); asset.removeAt(index); return CardModel( id: 20 - asset.length - 1, image: _image, key: UniqueKey() ); }); }
内容的提问来源于stack exchange,提问作者Nitneuq
相关产品推荐
相关产品推荐

