Flutter 使用 List.generate() 的坑!

1,486 阅读1分钟

今天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 的源码

image.png

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

image.png

3,在这里我们找到了为什么会触发异常的原因:

result list 中 E 的指定的类型为 Sub1, 因此修改 ESub2 会触发异常

image.png

4, 那么其他创建 List 的方法呢?

image.png

我们看到 除了 List.from 中 有定义类似的方法,但判断是数组就直接返回了

因此我们平时使用只需要注意 List.generate() 的使用即可。