今天Debug中,无意发现一个使用 List.generate() 需要注意的地方.
声明测试类
class Base {}
class Sub1 extends Base {}
class Sub2 extends Base {}
List.generate
List<Base> list = List.generate(5, (index) => Sub1()).toList();
list[1] = Sub2();
很简单的代码,原以为没啥问题
但直接运行报错: Unhandled exception: type 'Sub2' is not a subtype of type 'Sub1' of 'value'
这个时候我们改一改创建 List 的方式,使用下面三种方式之一,就会发现可以正常运行了。
List<Base> list = [
Sub1(),
Sub1(),
Sub1(),
Sub1(),
Sub1(),
];
or
List.from([...])
List.of([...])
list[1] = Sub2();
解决方法
那么为什么会出现这样的情况呢?
1,首先我们看一下 List 的源码
2, 我们看到它是使用 external 修饰,说明他是在其他类里面实现的, 我们找到它真正实现的类
# 打开你的 [Flutter SDK] 对应目录
cd [Your Flutter SDK Path]/bin/cache/dart-sdk/lib/_internal/vm/lib
# 找到 List external 真正的实现类路径
grep -n "class List" -r ./* --color=auto
# 打开 array_patch.dart
open ./array_patch.dart
3,在这里我们找到了为什么会触发异常的原因:
result list 中 E 的指定的类型为 Sub1, 因此修改 E 为 Sub2 会触发异常
4, 那么其他创建 List 的方法呢?
我们看到 除了 List.from 中 有定义类似的方法,但判断是数组就直接返回了
因此我们平时使用只需要注意 List.generate() 的使用即可。